对称密钥加密算法 对称轮数_选择Java加密算法第2部分–单密钥对称加密

对称密钥加密算法 对称轮数

抽象

这是涵盖Java加密算法的三部分博客系列的第2部分。 该系列涵盖如何实现以下功能:

  1. 使用SHA–512散列
  2. AES–256
  3. RSA–4096

这第二篇文章详细介绍了如何实现单密钥对称AES-256加密。 让我们开始吧。

免责声明

这篇文章仅供参考。 在使用所提供的任何信息之前,请认真思考。 从中学到东西,但最终自己做出决定,风险自负。

要求

我使用以下主要技术完成了本文的所有工作。 您可能可以使用不同的技术或版本来做相同的事情,但不能保证。

  • Java 1.8.0_152_x64
  • Java密码术扩展(JCE)的无限强度
  • NetBeans 8.2(内部版本201609300101)
  • Maven 3.0.5(与NetBeans捆绑在一起)

下载

访问我的GitHub页面以查看我所有的开源项目。 这篇文章的代码位于项目中: thoth-cryptography

对称加密

关于

对称加密算法基于单个密钥。 此密钥用于加密和解密。 因此,对称算法仅应在严格控制密钥的地方使用。

对称算法通常用于安全环境中的数据加密和解密。 一个很好的例子是确保微服务通信的安全。 如果OAuth-2 / JWT体系结构超出范围,则API网关可以使用对称算法的单密钥来加密令牌。 然后将此令牌传递给其他微服务。 其他微服务使用相同的密钥来解密令牌。 另一个很好的例子是电子邮件中嵌入的超链接。 电子邮件中的超链接包含一个编码的令牌,当单击该超链接时,该令牌允许自动登录请求处理。 此令牌是由对称算法生成的高度加密的值,因此只能在应用程序服务器上解码。 当然,任何时候都需要保护任何类型的密码或凭证,使用对称算法对它们进行加密,然后可以使用相同的密钥对字节进行解密。

截止目前的研究似乎表明,以下是最佳和最安全的单密钥,对称加密算法(Sheth,2017年,“选择正确的算法”,第2段):

  1. 算法: AES
  2. 模式: GCM
  3. 填充: PKCS5Padding
  4. 密钥大小: 256位
  5. IV大小: 96位

AES–256使用256位密钥, 需要安装Java密码学扩展(JCE)无限强度软件包。 让我们看一个例子。

注意: 256位密钥需要Java密码术扩展(JCE)无限强度软件包。 如果未安装,则最大为128位密钥。

如果尚未安装,请下载并安装Java Cryptography Extension(JCE)无限强度软件包。 需要使用256位密钥。 否则,必须将以下示例更新为使用128位密钥。

清单1是AesTest.java单元测试。 这是以下内容的完整演示:

  1. 生成并存储AES 256位密钥
  2. AES加密
  3. AES解密

清单2显示了AesSecretKeyProducer.java 。 这是一个帮助程序类,负责产生一个新密钥或从byte[]复制一个现有密钥。

清单3显示了ByteArrayWriter.java ,清单4显示了ByteArrayReader.java 。 这些是负责将byte[]写入文件的助手类。 由您决定如何存储密钥的byte[] ,但需要将其安全地存储在某个地方(文件,数据库,git存储库等)。

最后,清单5显示了Aes.java 。 这是一个帮助程序类,负责加密和解密。

清单1 – AesTest.java类

package org.thoth.crypto.symmetric;import java.io.ByteArrayOutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Optional;
import javax.crypto.SecretKey;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.thoth.crypto.io.ByteArrayReader;
import org.thoth.crypto.io.ByteArrayWriter;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class AesTest {static Path secretKeyFile;@BeforeClasspublic static void beforeClass() throws Exception {// Store the SecretKey bytes in the ./target diretory. Do// this so it will be ignore by source control.  We don't// want this file committed.secretKeyFile= Paths.get("./target/Aes256.key").toAbsolutePath();// Generate a SecretKey for the testSecretKey secretKey= new AesSecretKeyProducer().produce();// Store the byte[] of the SecretKey.  This is the// "private key file" you want to keep safe.ByteArrayWriter writer = new ByteArrayWriter(secretKeyFile);writer.write(secretKey.getEncoded());}@Testpublic void encrypt_and_decrypt_using_same_Aes256_instance() {// setupSecretKey secretKey= new AesSecretKeyProducer().produce(new ByteArrayReader(secretKeyFile).read());Aes aes= new Aes(secretKey);String toEncrypt= "encrypt me";// runbyte[] encryptedBytes= aes.encrypt(toEncrypt, Optional.empty());String decrypted= aes.decrypt(encryptedBytes, Optional.empty());// assertAssert.assertEquals(toEncrypt, decrypted);}public void encrypt_and_decrypt_with_aad_using_same_Aes256_instance() {// setupSecretKey secretKey= new AesSecretKeyProducer().produce(new ByteArrayReader(secretKeyFile).read());Aes aes= new Aes(secretKey);String toEncrypt= "encrypt me aad";// runbyte[] encryptedBytes= aes.encrypt(toEncrypt, Optional.of("JUnit AAD"));String decrypted= aes.decrypt(encryptedBytes, Optional.of("JUnit AAD"));// assertAssert.assertEquals(toEncrypt, decrypted);}@Testpublic void encrypt_and_decrypt_using_different_Aes256_instance()throws Exception {// setupSecretKey secretKey= new AesSecretKeyProducer().produce(new ByteArrayReader(secretKeyFile).read());Aes aesForEncrypt= new Aes(secretKey);Aes aesForDecrypt= new Aes(secretKey);String toEncrypt= "encrypt me";// runbyte[] encryptedBytes= aesForEncrypt.encrypt(toEncrypt, Optional.empty());ByteArrayOutputStream baos= new ByteArrayOutputStream();baos.write(encryptedBytes);String decrypted= aesForDecrypt.decrypt(baos.toByteArray(), Optional.empty());// assertAssert.assertEquals(toEncrypt, decrypted);}
}

清单2 – AesSecretKeyProducer.java类

package org.thoth.crypto.symmetric;import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class AesSecretKeyProducer {/*** Generates a new AES-256 bit {@code SecretKey}.** @return {@code SecretKey}, never null* @throws RuntimeException All exceptions are caught and re-thrown as {@code RuntimeException}*/public SecretKey produce() {KeyGenerator keyGen;try {keyGen = KeyGenerator.getInstance("AES");keyGen.init(256);SecretKey secretKey = keyGen.generateKey();return secretKey;} catch (Exception ex) {throw new RuntimeException(ex);}}/*** Generates an AES-256 bit {@code SecretKey}.** @param encodedByteArray The bytes this method will use to regenerate a previously created {@code SecretKey}** @return {@code SecretKey}, never null* @throws RuntimeException All exceptions are caught and re-thrown as {@code RuntimeException}*/public SecretKey produce(byte [] encodedByteArray) {try {return new SecretKeySpec(encodedByteArray, "AES");} catch (Exception ex) {throw new RuntimeException(ex);}}
}

清单3 – ByteArrayWriter.java类

package org.thoth.crypto.io;import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class ByteArrayWriter {protected Path outputFile;private void initOutputFile(Path outputFile) {this.outputFile = outputFile;}private void initOutputDirectory() {Path outputDirectory = outputFile.getParent();if (!Files.exists(outputDirectory)) {try {Files.createDirectories(outputDirectory);} catch (IOException e) {throw new RuntimeException(e);}}}public ByteArrayWriter(Path outputFile) {initOutputFile(outputFile);initOutputDirectory();}public void write(byte[] bytesArrayToWrite) {try (OutputStream os= Files.newOutputStream(outputFile);PrintWriter writer=  new PrintWriter(os);){for (int i=0; i<bytesArrayToWrite.length; i++) {if (i>0) {writer.println();}writer.print(bytesArrayToWrite[i]);}} catch (IOException ex) {throw new RuntimeException(ex);}}
}

清单4 – ByteArrayReader.java类

package org.thoth.crypto.io;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Scanner;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class ByteArrayReader {protected Path inputFile;public ByteArrayReader(Path inputFile) {this.inputFile = inputFile;}public byte[] read() {try (Scanner scanner=  new Scanner(inputFile);ByteArrayOutputStream baos= new ByteArrayOutputStream();){while (scanner.hasNext()) {baos.write(Byte.parseByte(scanner.nextLine()));}baos.flush();return baos.toByteArray();} catch (IOException ex) {throw new RuntimeException(ex);}}
}

清单5 – Aes.java类

package org.thoth.crypto.symmetric;import java.security.SecureRandom;
import java.util.Optional;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;/**** @author Michael Remijan mjremijan@yahoo.com @mjremijan*/
public class Aes {// If you don't have the Java Cryptography Extension// (JCE) Unlimited Strength packaged installed, use// a 128 bit KEY_SIZE.public static int KEY_SIZE = 256;public static int IV_SIZE = 12; // 12bytes * 8 = 96bitspublic static int TAG_BIT_SIZE = 128;public static String ALGORITHM_NAME = "AES";public static String MODE_OF_OPERATION = "GCM";public static String PADDING_SCHEME = "PKCS5Padding";protected SecretKey secretKey;protected SecureRandom secureRandom;public Aes(SecretKey secretKey) {this.secretKey = secretKey;this.secureRandom = new SecureRandom();}public byte[] encrypt(String message, Optional<String> aad) {try {// Transformation specifies algortihm, mode of operation and paddingCipher c = Cipher.getInstance(String.format("%s/%s/%s",ALGORITHM_NAME,MODE_OF_OPERATION,PADDING_SCHEME));// Generate IVbyte iv[] = new byte[IV_SIZE];secureRandom.nextBytes(iv); // SecureRandom initialized using self-seeding// Initialize GCM ParametersGCMParameterSpec spec = new GCMParameterSpec(TAG_BIT_SIZE, iv);// Init for encryptionc.init(Cipher.ENCRYPT_MODE, secretKey, spec, secureRandom);// Add AAD tag data if presentaad.ifPresent(t -> {try {c.updateAAD(t.getBytes("UTF-8"));} catch (Exception e) {throw new RuntimeException(e);}});// Add message to encryptc.update(message.getBytes("UTF-8"));// Encryptbyte[] encryptedBytes= c.doFinal();// Concatinate IV and encrypted bytes.  The IV is needed later// in order to to decrypt.  The IV value does not need to be// kept secret, so it's OK to encode it in the return value//// Create a new byte[] the combined length of IV and encryptedBytesbyte[] ivPlusEncryptedBytes = new byte[iv.length + encryptedBytes.length];// Copy IV bytes into the new arraySystem.arraycopy(iv, 0, ivPlusEncryptedBytes, 0, iv.length);// Copy encryptedBytes into the new arraySystem.arraycopy(encryptedBytes, 0, ivPlusEncryptedBytes, iv.length, encryptedBytes.length);// Returnreturn ivPlusEncryptedBytes;} catch (Exception e) {throw new RuntimeException(e);}}public String decrypt(byte[] ivPlusEncryptedBytes, Optional<String> aad) {try {// Get IVbyte iv[] = new byte[IV_SIZE];System.arraycopy(ivPlusEncryptedBytes, 0, iv, 0, IV_SIZE);// Initialize GCM ParametersGCMParameterSpec spec = new GCMParameterSpec(TAG_BIT_SIZE, iv);// Transformation specifies algortihm, mode of operation and paddingCipher c = Cipher.getInstance(String.format("%s/%s/%s",ALGORITHM_NAME,MODE_OF_OPERATION,PADDING_SCHEME));// Get encrypted bytesbyte [] encryptedBytes = new byte[ivPlusEncryptedBytes.length - IV_SIZE];System.arraycopy(ivPlusEncryptedBytes, IV_SIZE, encryptedBytes, 0, encryptedBytes.length);// Init for decryptionc.init(Cipher.DECRYPT_MODE, secretKey, spec, secureRandom);// Add AAD tag data if presentaad.ifPresent(t -> {try {c.updateAAD(t.getBytes("UTF-8"));} catch (Exception e) {throw new RuntimeException(e);}});// Add message to decryptc.update(encryptedBytes);// Decryptbyte[] decryptedBytes= c.doFinal();// Returnreturn new String(decryptedBytes, "UTF-8");} catch (Exception e) {throw new RuntimeException(e);}}
}

摘要

加密并不容易。 简单的示例将为您的应用程序带来带有安全漏洞的实现。 如果您需要单密钥对称加密算法,请使用具有256位密钥和96位IV的密码AES / GCM / PKCS5Padding。

参考资料

  • Java密码术扩展(JCE)无限强度。 (nd)。 检索自http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html 。
  • Sheth,M.(2017年4月18日)。 Java密码学中的加密和解密。 从https://www.veracode.com/blog/research/encryption-and-decryption-java-cryptography检索。
  • cpast [表示GCM IV是96位,即96/8 = 12字节]。 (2015年6月4日)。 使用AES–256加密时,我可以使用256位IV [Web日志注释]。 从https://security.stackexchange.com/questions/90848/encrypting-using-aes-256-can-i-use-256-bits-iv检索
  • Bodewes [强烈建议将GCM IV设置为12个字节(12 * 8 = 96),但可以是任意大小。 其他尺寸将需要其他计算],M。(2015年7月7日)。 密文和标签大小以及在GCM模式下使用AES进行IV传输[Web日志注释]。 从https://crypto.stackexchange.com/questions/26783/ciphertext-and-tag-size-and-iv-transmission-with-aes-in-gcm-mode检索。
  • Figlesquidge。 (2013年10月18日)。 “密码”和“操作模式”之间有什么区别? [网络日志评论]。 从https://crypto.stackexchange.com/questions/11132/what-is-the-difference-between-a-cipher-and-a-mode-of-operation检索。
  • Toust,S.(2013年2月4日)。 为什么对称和非对称加密之间的建议密钥大小会有很大差异? 取自https://crypto.stackexchange.com/questions/6236/why-does-the-recommended-key-size-between-symmetric-and-asymmetric-encryption-di 。
  • 卡罗宁(I.)(2012年10月5日)。 密钥,IV和随机数之间的主要区别是什么? 从https://crypto.stackexchange.com/questions/3965/what-is-the-main-difference-between-a-key-an-iv-and-a-nonce检索。
  • 分组密码操作模式。 (2017年11月6日)。 维基百科。 取自https://zh.wikipedia.org/wiki/Block_cipher_mode_of_operation#Initialization_vector_.28IV.29

翻译自: https://www.javacodegeeks.com/2017/12/choosing-java-cryptographic-algorithms-part-2-single-key-symmetric-encryption.html

对称密钥加密算法 对称轮数

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/334114.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 命令之 unxz -- 解压缩文件

文章目录一、命令介绍二、命令示例&#xff08;一&#xff09;解压文件&#xff08;二&#xff09;将指定的压缩文件解压缩到指定的目录下&#xff0c;且可以重命名一、命令介绍 unxz 命令用于解压缩使用 xz 压缩的文件包&#xff0c;实际 unxz 相当于 xz -d 二、命令示例 &…

计算机配置界面在那,在哪里设置关机画面?设置为原来的经典界面?

电脑故障现象&#xff1a;我用的系统是winxp&#xff0c;关机出现的画面是那种下拉式菜单“注销、重启、关机、取消”&#xff0c;我想用的不是这种下拉式菜单&#xff0c;是并列图标那种&#xff0c;请问在哪里设置&#xff1f;(电脑入门到精通网 www.58116.cn)一般解决方法&a…

程序代码移植和烧录需要注意什么_购买建站模板需要注意什么问题

购买建站模板需要注意什么问题?现在市面上出现的建站工具质量参差不齐&#xff0c;但是如此多的建站模板&#xff0c;应该选择哪个呢&#xff1f;如此多的建站工具平台应该怎么样选择呢&#xff1f;这里我们来聊一聊。北京网站建设公司—东浩联创现在非常多站长都会购买一些定…

java字符串各个字符计数_没有科学计数法的Java十进制数的简单字符串表示形式...

java字符串各个字符计数Java中用于十进制数字的主要类型 /对象是float / Float &#xff0c; double / Double和BigDecimal 。 在每种情况下&#xff0c;其“默认”字符串表示形式都是“计算机科学计数法”。 这篇文章演示了一些简单的方法&#xff0c;可以在没有科学符号的情况…

python操纵excel的方法_python操作Excel的几种方式

Python对Excel的读写主要有xlrd、xlwt、xlutils、openpyxl、xlsxwriter几种。首先你的本地要有包文件&#xff0c;安装上面的包文件如下图1.xlrd主要是用来读取excel文件import xlrdworkbook xlrd.open_workbook(u有趣装逼每日数据及趋势.xls)sheet_names workbook.sheet_name…

计算机线性输入录音原理,耳机输出的模拟信号-怎样把声音通过线路录入电脑?比方说,收音机的耳机输出孔,接线(串 爱问知识人...

啊&#xff1f;有这样的东西吗&#xff1f;想把收音机里的声音录下来很简单。你在电脑上收听就可以了。这和软件无关。是因为硬件。买了转接头也是没用的。因为计算机声卡只能通过计算机来放音然后录制。其实你指的就是放音录制而不是通过其他线路来录制。这和外放的设备无关。…

Linux 如何查看命令所在位置/查看命令文件所在位置

文章目录whichtypewhereiswhich which 命令的作用是在环境变量 PATH 所指定的路径中&#xff0c;搜索某个系统命令的位置&#xff0c;并且返回第一个搜索结果。 查看命令详情&#xff0c;猛戳 《Linux 命令之 which – 查找并显示给定命令的绝对路径》 [roothtlwk0001host ~…

java 方法 示例_Java 9示例–收集的工厂方法–创建不可修改的列表,集合和映射...

java 方法 示例大家好&#xff0c;这是我在该博客上发表的有关Java 9功能的第一篇文章&#xff0c;今天您将了解我最喜欢的功能“收集的工厂方法” &#xff0c;它是JEP 269的一部分。JEP代表JDK增强建议。 如果您曾经在Groovy或Kotlin工作过&#xff0c;那么您就会知道使用集合…

python中的深拷贝_Python中的深拷贝和浅拷贝

前言&#xff1a;在认识深浅拷贝的时候&#xff0c;先了解python中的可变类型与不可变类型。 以及 python中的传参到底是传递值还是传递引用(内存地址)python中的可变数据类型主要有 :(列表,字典) 指的是在内存地址(id)不变的情况下&#xff0c;可变数据类型的‘值’是可以发生…

JDK 命令之 jar -- 压缩/解压缩工具

文章目录一、命令介绍二、命令格式三、常用选项四、命令示例&#xff08;一&#xff09;将指定目录打成 jar 包&#xff08;二&#xff09;将指定目录打成 jar 包&#xff0c;且不生成文件 META-INF/MANIFEST.MF&#xff08;三&#xff09;打包时指定文件 MANIFEST.MF&#xff…

高一计算机算法教案,高一信息技术第六章“第一节程序设计的基本方法”教案设计...

一、教学目标1&#xff0e;理解算法的概念&#xff1b;2&#xff0e;知道两种算法的描述方法—语言描述法和流程图的区别3&#xff0e;能初步利用算法解决简单的问题。4&#xff0e;培养学生的理论联系实际能力和动手操作能力。二、教学重难点1&#xff0e;重点&#xff1a;算法…

openshift安装_云幸福–如何在几分钟内安装新的OpenShift Container Platform 3.7

openshift安装此安装需要安装Red Hat Middleware产品流&#xff08;预配置的容器选项&#xff09;以及所有其他功能&#xff0c;例如源容器&#xff0c;映像容器和.Net Core容器。自OpenShift容器平台发布以来&#xff0c;我一直希望提供一个简单的方法。 &#xff0c;完全配置…

python 实现语音转文字_python3实现语音转文字(语音识别)和文字转语音(语音合成)...

话不多说&#xff0c;直接上代码运行截图1.语音合成------->执行&#xff1a;结果&#xff1a;输入要转换的内容&#xff0c;程序直接帮你把转换好的mp3文件输出(因为下一步–语音识别–需要.pcm格式的文件&#xff0c;程序自动执行格式转换&#xff0c;同时生成17k.pcm文件…

Linux 命令之 7z(7-zip) -- 压缩/解压文件

文章目录 一、命令介绍(一)主要特征1.使用 LZMA 算法2.支持多种格式(二)退出代码的含义(三)关于通配符(四)关于覆盖文件的提示回应二、命令格式三、常用子命令四、常用选项五、命令示例(一)测试压缩档案的完整性(二)将指定的压缩档解压到指定的目录下(三)列出指定…

简单的计算机程序代码,优秀程序员通过简单代码,窥探电脑编程中强大的数组操作功能...

优秀程序员通过简单代码&#xff0c;窥探电脑编程中强大的数组操作功能。编程语言中&#xff0c;数组是一个非常重要的概念&#xff0c;也是一种很常用的类型。本文中通过javascript语言的代码实例&#xff0c;展现编程中数组的魅力。在javascript语言中&#xff0c;数组Array类…

java 示例_功能Java示例 第3部分–不要使用异常来控制流程

java 示例这是称为“ Functional Java by Example”的系列文章的第3部分。 我在本系列的每个部分中开发的示例是某种“提要处理程序”&#xff0c;用于处理文档。 在前面的部分中&#xff0c;我从一些原始代码开始&#xff0c;并应用了一些重构来描述“什么”而不是“如何”。…

Linux 命令之 gzip -- 压缩和解压文件

文章目录一、命令介绍二、常用选项三、命令示例&#xff08;一&#xff09;将指定目录下的每个文件压缩成 .gz 文件&#xff08;二&#xff09;解压指定目录下的每个压缩文件&#xff08;三&#xff09;显示指定目录下每个压缩文件的信息&#xff0c;并不解压&#xff08;四&am…

python读取tiff数据_opencv-python读取tiff影像,并展示

pencv-python可以读取各类图片&#xff0c;然后对图像进行处理&#xff0c;结合矩阵操作&#xff0c;可以非常方便的对图像进行各类操作&#xff0c;下面就展示一个简单的demo&#xff0c;用opencv-python读取图像并展示出来。Opencv的库安装可能比较麻烦一点。# 导入cv模块imp…

win7 计算机定时关机脚本,win7怎么定时关机?win7定时关机设置两种方法

当我们在操作电脑的时候&#xff0c;有时会有需要定时关机&#xff0c;或者不在电脑前操作是需要过段时间自动关机&#xff0c;但是Win7系统没有自带的定时关机软件&#xff0c;很多电脑用户又不喜欢安装第三方软件来完成该操作。那么win7怎么定时关机&#xff1f;本文为大家介…

Linux 命令之 gunzip -- 用来解压缩文件

文章目录一、命令介绍二、常用选项三、命令示例&#xff08;一&#xff09;解压文件&#xff0c;删除原文件&#xff08;二&#xff09;解压文件&#xff0c;并保留原文件&#xff08;三&#xff09;解压文件到其它目录下&#xff08;四&#xff09;指定后缀名来解压文件一、命…