对称加密算法 简单的来说,对称加密算法就是加密的密钥与解密的密钥是相同的。 常用对称加密算法
DES(Data Encryption Standard)
3DES(DES加强版,使用3次DES计算,Triple DES,DESede)
AES(Advanced Encryption Standard,3DES加强版)
AES AES的具体实现,在下面的参考文章中。 在这里了解到,AES的几个模式
ECB模式(电子密码本模式)
CBC模式(密码分组链接:Cipher-block chaining)
CFB模式(密文反馈:Cipher feedback)
在块加密中,通常要整数长度的数据,但用户输入的数据不一定是整数长度,所以要把数据进行填充,就有几种填充方式。 AES加密模式和填充方式(其实还有还几种填充方式没写上,开始时候也在这里绕了一下)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 算法/模式/ 填充 16 字节加密后数据长度 不满16 字节加密后长度 AES/CBC/ NoPadding 16 不支持 AES/CBC/ PKCS5Padding 32 16 AES/CBC/ ISO10126Padding 32 16 AES/CFB/ NoPadding 16 原始数据长度 AES/CFB/ PKCS5Padding 32 16 AES/CFB/ ISO10126Padding 32 16 AES/ECB/ NoPadding 16 不支持 AES/ECB/ PKCS5Padding 32 16 AES/ECB/ ISO10126Padding 32 16 AES/OFB/ NoPadding 16 原始数据长度 AES/OFB/ PKCS5Padding 32 16 AES/OFB/ ISO10126Padding 32 16 AES/PCBC/ NoPadding 16 不支持 AES/PCBC/ PKCS5Padding 32 16 AES/PCBC/ ISO10126Padding 32 16
几种AES 常见的加密套件 这是ss中可选的加密套件
“aes-128-cfb”
“aes-192-cfb”
“aes-256-cfb”
“aes-128-ofb”
“aes-192-ofb”
“aes-256-ofb”
中间的就初始化向量的长度,后面就是模式。
java代码的AES实现 测试代码 1 2 3 4 5 6 7 8 public static void main(String[] args) throws Exception { String passwordkey= "123123"; String content= "The quick brown fox jumps over a lazy dog."; byte[] encrypted = encrypt(content, passwordkey); System .out .println("after encrypt: "+new String(encrypted )); String decrypted = decrypt(encrypted , passwordkey); System .out .println("after decrypt: "+decrypted); }
加密方法 主要步骤:
生成初始化向量
哈希 key(不是必须的,但是因为AES要一个16字节的密钥,把密码变成16字节)
加密
合并初始化向量IV 和加密部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public static byte[] encrypt(String plainText, String key) throws Exception { byte[] clean = plainText.getBytes(); // 随机生成从初始化向量 IV. int ivSize = 16 ; byte[] iv = new byte[ivSize]; SecureRandom random = new SecureRandom(); random.nextBytes(iv); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); // 哈希 key. MessageDigest digest = MessageDigest.getInstance("SHA-256"); digest.update (key.getBytes("UTF-8")); byte[] keyBytes = new byte[16 ]; System .arraycopy(digest.digest(), 0 , keyBytes, 0 , keyBytes.length); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES"); // 加密 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encrypted = cipher.doFinal(clean); // 合并初始化向量IV 和加密部分 byte[] encryptedIVAndText = new byte[ivSize + encrypted .length]; System .arraycopy(iv, 0 , encryptedIVAndText, 0 , ivSize); System .arraycopy(encrypted , 0 , encryptedIVAndText, ivSize, encrypted .length); return encryptedIVAndText; }
解密部分 与加密部分相反
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public static String decrypt(byte[] encryptedIvTextBytes, String key) throws Exception { int ivSize = 16 ; int keySize = 16 ; byte[] iv = new byte[ivSize ] ; System . arraycopy(encryptedIvTextBytes, 0 , iv, 0 , iv.length); IvParameterSpec ivParameterSpec = new IvParameterSpec(iv ) ; int encryptedSize = encryptedIvTextBytes.length - ivSize; byte[] encryptedBytes = new byte[encryptedSize ] ; System . arraycopy(encryptedIvTextBytes, ivSize, encryptedBytes, 0 , encryptedSize); byte[] keyBytes = new byte[keySize ] ; MessageDigest md = MessageDigest . getInstance("SHA-256" ) ; md.update(key.getBytes() ); System . arraycopy(md.digest() , 0 , keyBytes, 0 , keyBytes.length); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes , "AES" ) ; Cipher cipherDecrypt = Cipher . getInstance("AES/CBC/PKCS5Padding" ) ; cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] decrypted = cipherDecrypt.do Final(encryptedBytes ) ; return new String(decrypted ) ; }
总结 对称加密算法有五个关键因素:算法、工作模式、填充模式、初始化向量、密钥。
“算法、工作模式、填充模式”在Cipher获取实例时进行指定,如Cipher.getInstance("AES/CBC/PKCS5Padding");
。
“密钥、初始化向量”在Cipher初始化时,进行指定,如cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
doFinal
进行具体的处理
密钥由字节变对像要经过SecretKeySpec
包装
初始化向量由字节变为对像要经过IvParameterSpec
包装,初始化向量长度,AES是16位,DES是8位。
如果做验证,推荐一个在线加解密的站点,用是JSEncrypt。https://blog.zhengxianjun.com/online-tool/rsa/
参考