制作密钥
KeyPairGenerator
对于非对称加密,他区分公钥和私钥 我们可以用
KeyPairGenerator
来为我们生成秘钥对。我们根据一个算法名称得到该生成器,调用
generateKeyPair()
来生成秘钥对
现在我们来生成下RSA算法的秘钥对
@Test@DisplayName("通过算法 创建密钥对生成器")publicvoidgetInstanceByAlgorithm()throwsNoSuchAlgorithmException{String algorithm =AsymmetricAlgorithm.RSA.getValue();KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);KeyPair keyPair = keyPairGenerator.generateKeyPair();}
KeyPair
得到
KeyPair
对象,里面就能拿到公钥和私钥啦~~
KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();
对于对称加密,加密和解密都用的用一个钥匙,我们可以用
KeyGenerator
来拿到这个秘钥,我们来拿下AES算法的秘钥吧
@Test@DisplayName("通过算法 创建密钥生成器")publicvoidgetInstance()throwsNoSuchAlgorithmException{String value =SymmetricAlgorithm.AES.getValue();KeyGenerator keyGenerator =KeyGenerator.getInstance(value);System.out.println(keyGenerator);// javax.crypto.KeyGenerator@10e92f8fString secretKeyStr =Base64.getEncoder().encodeToString(secretKey.getEncoded());}
Java安全框架本身内置了许多对称安全算法的实现,下面我们分别来获取下不同安全算法的秘钥
- DES
String algorithm ="DES";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// com.sun.crypto.provider.DESKey@186b4
你要是觉得不够安全,再加随机字符做进一步增强
String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="DES";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);
keyGenerator.init(secureRandom);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// com.sun.crypto.provider.DESKey@fffe7ba8
- DESede
String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// com.sun.crypto.provider.DESedeKey@b069a993
String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);
keyGenerator.init(secureRandom);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// com.sun.crypto.provider.DESedeKey@4f964239
- AES
String algorithm ="AES";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// javax.crypto.spec.SecretKeySpec@1745d
String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="AES";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);
keyGenerator.init(secureRandom);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// javax.crypto.spec.SecretKeySpec@1745d
- RC2
String algorithm ="RC2";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// javax.crypto.spec.SecretKeySpec@1be5d
String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="RC2";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);
keyGenerator.init(secureRandom);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// javax.crypto.spec.SecretKeySpec@fffe4f87
- ARCFOUR
String algorithm ="ARCFOUR";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// javax.crypto.spec.SecretKeySpec@1be5d
String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="ARCFOUR";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);
keyGenerator.init(secureRandom);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// javax.crypto.spec.SecretKeySpec@fffe4f87
- Blowfish
String algorithm ="Blowfish";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// javax.crypto.spec.SecretKeySpec@1be5d
可能你的需求,内置的算法不能满足你的需要,那么我们可以使用第三方lib,支撑一下。比如国密算法SM4,Java设计得很好的是,他提供了一个口子,让你注入这些三方算法。从而兼容他的安全框架体系。
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on --><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version></dependency>
//请说明你的算法来源Security.addProvider(newBouncyCastleProvider());String algorithm ="SM4";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);// javax.crypto.spec.SecretKeySpec@1be5d
呵呵呵,是不是无缝衔接上了。
@Test@DisplayName("生成 SM4 密钥算法的密钥 并使用 SecureRandom")publicvoidgenerateSM4SecretKeyUseSecureRandom()throwsNoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException,NoSuchProviderException{Security.addProvider(newBouncyCastleProvider());String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="SM4";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm,BouncyCastleProvider.PROVIDER_NAME);
keyGenerator.init(newSecureRandom());SecretKey secretKey = keyGenerator.generateKey();System.out.println(secretKey);//javax.crypto.spec.SecretKeySpec@1bd4b}
SecureRandom
安全随机数,是Random的一个子类。针对安全框架使用的。
我们知道,Random类中实现的随机算法是伪随机,也就是有规则的随机。在进行随机时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。
相同种子数的Random对象,相同次数生成的随机数字是完全相同的。也就是说,两个种子数相同的Random对象,生成的随机数字完全相同。
所以在需要频繁生成随机数,或者安全要求较高的时候,不要使用Random,因为其生成的值其实是可以预测的。
- SecureRandom类提供加密的强随机数生成器 (RNG)
- 当然,它的许多实现都是伪随机数生成器 (PRNG) 形式,这意味着它们将使用确定的算法根据实际的随机种子生成伪随机序列
- 也有其他实现可以生成实际的随机数
- 还有另一些实现则可能结合使用这两项技术
SecureRandom
和
Random
都是,也是如果种子一样,产生的随机数也一样: 因为种子确定,随机数算法也确定,因此输出是确定的。
只是说,
SecureRandom
类收集了一些随机事件,比如鼠标点击,键盘点击等等,SecureRandom 使用这些随机事件作为种子。这意味着,种子是不可预测的,而不像Random默认使用系统当前时间的毫秒数作为种子,有规律可寻。
@Test@DisplayName("内置两种随机数算法,NativePRNG 和 SHA1PRNG,看实例化的方法了。")publicvoidgetInstanceUseNativePRNG()throwsNoSuchAlgorithmException{String userKey ="wangnaixing@springBoot";String randomAlgorithm ="NativePRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);
secureRandom.setSeed(userKey.getBytes());for(int i =0; i <10; i++){byte[] bytes = secureRandom.generateSeed(5);System.out.println(Arrays.toString(bytes));}/**
* [116, 89, 89, 98, 90]
* [79, 36, -45, -1, 82]
* [-93, -109, 88, 91, 82]
* [-116, 45, -4, -91, 97]
* [-100, 108, 29, -68, 119]
* [21, 77, -48, 125, -104]
* [-117, 110, -95, 93, -113]
* [3, 42, 96, -5, -42]
* [92, -32, -24, -21, -127]
* [114, 31, 101, 93, -116]
*/}
@Test@DisplayName("使用 SHA1PRNG 创建实例 用的比较多 ")publicvoidgetInstanceSHA1PRNG()throwsNoSuchAlgorithmException{String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);
secureRandom.setSeed(userKey.getBytes(StandardCharsets.UTF_8));for(int i =0; i <10; i++){byte[] bytes = secureRandom.generateSeed(5);System.out.println(Arrays.toString(bytes));}/**
* [8, 70, 101, -54, -74]
* [57, 110, -23, 100, 20]
* [108, -45, -96, 45, -90]
* [44, 69, -69, -59, -44]
* [-54, 53, 20, 54, 87]
* [-92, -94, 101, 51, -98]
* [-48, 113, -73, -116, 123]
* [104, 104, 113, 43, 66]
* [60, 104, -70, 10, 48]
* [63, -40, -97, -104, 86]
*/}
KeyFactory
一个具体实例,前端老哥存的那种很长一串的字符串,Java也想到了,给你提供一个工厂,将实例字面量转为Java对象Key对象的。
来,我们看看前端老哥存的那种很长一串字符串,如何转为Java对象的,下面对标非对称加密情形。
@Test@DisplayName("初始化RSA 算法的公钥和私钥")publicvoidgeneratePublicKeyAndPrivateKey()throwsNoSuchAlgorithmException,InvalidKeySpecException{String algorithm =AsymmetricAlgorithm.RSA.getValue();KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();byte[] privateKeyEncoded = privateKey.getEncoded();byte[] publicKeyEncoded = publicKey.getEncoded();String privateKeyStr =Base64.getEncoder().encodeToString(privateKeyEncoded);System.out.println(privateKeyStr);//我留着,不对外暴露FileUtil.writeString(privateKeyStr,newFile("1.txt"),StandardCharsets.UTF_8);String publicKeyStr =Base64.getEncoder().encodeToString(publicKeyEncoded);FileUtil.writeString(publicKeyStr,newFile("2.txt"),StandardCharsets.UTF_8);System.out.println(publicKeyStr);//给前端老哥}
privateString privateKeyStr ="MIIG/AIBADANBgkqhkiG9w0BAQEFAASCBuYwggbiAgEAAoIBgQC7z7xGY2ow9QCnl8NbXKmh9EYfulqCWhaYFsQYcuN5OnSw1qtIwFDLbgN5FdyyuQ7JOyspXQEYaRrnMNICcRJZS8yIJfJLvhl8EvGocgBH4iIjBDRq+gVkAfvg3/wqAya9lg26dypfYBgFCNM9VJZOEtBCKp+agAhtYrilUvP+BRxZxRRySvi+DbUSHuknRIvWjvqj8NT2z7rxFLuOdG7L+o1ySIyf9XNXGgX6AuIa98LdTpZe23ubWoUcpZomz7d2nisPmpmeka8JeMS1I29yaibEd+kR5/v52DZqUlUgbAPGES3rmhpLyBoHcyFEHN3puaEugvBwkPAss0771rjjtI4GPllV5o4CDSoYPG0FpBSxGD9ob4Rr7c6YYdUSAdav8qK75DbSD3nVoy/Io9A2PwaAaQWLtl4Sf/8orMCGSLwrhqpGMnCWw5BpAw5lC8XHzDwDQpNwfBHPhgMVttWgDJpPUUGRmPuMM0uYXaomX6T1oZNVGe49UUm1OJhWmKUCAwEAAQKCAX9WBS86GEfL2XyVaF32kmzG0fWQkqR0ooNroGS/0V2LCioIpRbR9zzaateL83QKPtqG3HC4nJHxhGIxFHZctZZIDyEdM+SS581oMw5ufr5GBVOxzf3G8/AMqv4VlAaIEgFTtY+J5dChOpwehdDzDDhNPvteCzHwIRO7DOz84ElUrF69EP6r/mMAjhpMkf3zwOIpeATL3ppdpEyKmeNNu5JZDgl9lkxsCFib5RjQ2npjNQMjZBVEwA8k759Wss3Mrd6J3+Y2ffliiMT2s8RrVYEj8gT2ESi6tGsKT4Y/CShd8ZVRBhT1UtZEOLyDtycm9kjhGRD0FpOx/bPLZd3UBN7yJCGVYev9j5mDAtkZjp8teMEtQwohYIAUar0E6/9V0oGw0k+8qujJxOCS6fQ45MzHy0aEza4GMeTyj2/juZkbcj5vk3IVYAbJdzTICx0wga7cs/3PO6Pw1E61ozGTAhZlSYCtKYug3hGrZUwTEt0Jqa4VoKoxj2VWDxnJpV8GaQKBwQDmqQyDNDNRFtV/druQkvKZcNKx5cHTD6ESAY5DGvw0Wn90QHc0We/f9xilFFpHBx988YFbtc7tbE6kuRf087XSvQpLZ9edm45uNB1NhmLi7UuoFohGUFJuf/q293wIusX9rC7T6ENz14v56pHTGa6Wm/o0cbFqE4DAfeHYUQpVVrfdzNSbYXYUKASULUZ07SaQOweUlpVwGSbk9AC45rhYVOOQGzMsv3PpYQWeMbnVZPIw+7xFuyk2iGzXLAV5j7MCgcEA0HGheOondYhPt/3+mfrZqjNYuv3kPZIFlebVDH39mIDFOLxPhzwwFx8pWOInBdu0LM4fpy0sdwQAyLRj+aEXuWeRfTHySr49gxXrxVfrxR9h9uwM4aJyZ5oYPa51s7x+dY+/tr7N5ayjDUIIHrbiaF5mNNrGL2rM6UPSctmZXAUTHcueOhzGknJIOIS7aCCeJmwPGXDCYcFVxRRYgToAP5fMMZ7HNZqc0hn81+J0AMP5l9+XDrRR8feXoKAUkkpHAoHAI7Z61HmplF2HstOMWOcXnsBELv0W1HnwA1ywTR2JfQWiBDrS+g0Owct9SlnrXGHy8yJlV/C/WC1Tw9dQqUFunnFcfa5XSPTDybZR7yXme6In+595fAGFscwo4llRH/zjGNKm8XJdtzrhVlGGQHwSdwkxZRtRT84zOhqDdD2f7vSdRT8oj+I4KQjFJLgZ15K8TMqG8u+ZtaB/UCWjUv2N/0ctcKt1cfE2niTCfOrQDgUyJnljfhxrViErUOlk85xXAoHAWVXaFrCEaOMbB4hcbjIMx91p0fqur5S9wBlGhiwZXBsUa9SJYTRyh/ZbCjUi9GfNOMa+2i+KNxgIHfzyPDLGsDerKzUU2uPeCSiD+/hKnBlvKxzQCIRO9AgfC5CR8Y5/xHLvf6sXI7Bx0WTThhZrwr9ynoSFHB1x5SekMoUALWgfYU27aryafnlsaoy4pVAVd/IoJoclSDBMSkMGC5yILrkoUrvyNQ8m1wU8UGpFvW5Ass6pNywhUssCuVzidDBRAoHBAL6hSYBNDF5aGRPOPjtO13YCD0vjeFZdytpnlcEhiLN1W9Hpv8cmzCoi2bgPeCfVqxvdIdI4VAmws/7omDEIwHWe+FsJevIGfszs3m5NZsDB7KTfK8X8e7+3i15FkeSEZtsqMadiYLDi00hutMOUa1vQn0OOXOOvvKUZwAVstYMUDR6lGQmVC7Dv036mEfXg+s2xXVAmtGAAl4OhnpQyTHSSH30+Cbf23OxL0P6xFMLHlOw41ZVHiMuVMxuFPXqrpQ==";privateString publicKeyStr = "MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAu8+8RmNqMPUAp5fDW1ypofRGH7pagloWmBbEGHLjeT
@Test@DisplayName("通过Key工厂将私钥字符串 变成 Java中的私钥对象")publicvoidgeneratePrivate()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeySpecException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException{String algorithm =AsymmetricAlgorithm.RSA.getValue();//原内容进行了Base64编码,现在进行 解码成 字节数组byte[] encodeKey =Base64.getDecoder().decode(privateKeyStr);PKCS8EncodedKeySpec pkcs8EncodedKeySpec =newPKCS8EncodedKeySpec(encodeKey);KeyFactory keyFactory =KeyFactory.getInstance(algorithm);//拿到了Java抽象的对象 PrivateKeyPrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);}
@Test@DisplayName("通过Key工厂将公钥字符串 变成 Java中的公钥对象")publicvoidgeneratePublic()throwsNoSuchAlgorithmException,InvalidKeySpecException{String algorithm =AsymmetricAlgorithm.RSA.getValue();;byte[] encodedKey =Base64.getDecoder().decode(publicKeyStr);X509EncodedKeySpec x509EncodedKeySpec =newX509EncodedKeySpec(encodedKey);KeyFactory keyFactory =KeyFactory.getInstance(algorithm);PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);}
如果你业务需要转为KeySpect的话,KeyFactory也可以做这样的转换工作
@Test@DisplayName("返回给定密钥的规范(密钥材料)")publicvoidgetKeySpec()throwsNoSuchAlgorithmException,InvalidKeySpecException{String algorithm =AsymmetricAlgorithm.RSA.getValue();KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();KeyFactory keyFactory =KeyFactory.getInstance(algorithm);// 公钥的密钥材料X509EncodedKeySpec x509EncodedKeySpec = keyFactory.getKeySpec(publicKey,X509EncodedKeySpec.class);// 私钥的密钥材料PKCS8EncodedKeySpec pkcs8EncodedKeySpec = keyFactory.getKeySpec(privateKey,PKCS8EncodedKeySpec.class);}
不能盲目认为非对称加密,两把钥匙就很安全了,听说RSA有人用量子计算机破解了,你只得加大bit位,减缓被大佬破解的可能性。来看看对称加密。对称加密是用户不需要关心那种RSA那种秘钥,谁没事在记事本记下一个这玩意。用户只需要一个口令,这个口令用户自己决定,可以是123456,这极度好记,就能把数据加解密。
SecretKeyFactory
PBE家族
对称加密的算法就很多了,算法和Key一对一。我们如果生产出对称加密的秘钥呢?看下
SecretKeyFactory
,该工厂就是专门做这个事情的。
@Test@DisplayName("生成密钥,使用 PBE")publicvoidGenerateSecretKeyByPBE()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBE";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(secretKey);// com.sun.crypto.provider.PBEKey@431249b0}
@Test@DisplayName("生成密钥,使用PBEWithMD5AndDES")publicvoidGenerateSecretKeyByPBEWithMD5AndDES()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithMD5AndDES";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey pebWithMD5AndDesSecretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(pebWithMD5AndDesSecretKey);// com.sun.crypto.provider.PBEKey@431249b0}
@Test@DisplayName("生成密钥,使用 PBEWithMD5AndTripleDES")publicvoidGenerateSecretKeyByPBEWithMD5AndTripleDES()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithMD5AndTripleDES";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(secretKey);// com.sun.crypto.provider.PBEKey@9297d5d2}
@Test@DisplayName("生成密钥,使用 PBEWithSHA1AndDESede")publicvoidGenerateSecretKeyByPBEWithSHA1AndDESede()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithSHA1AndDESede";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(secretKey);// com.sun.crypto.provider.PBEKey@9297d5d2}
@Test@DisplayName("生成密钥,使用 PBEWithSHA1AndRC2_40")publicvoidGenerateSecretKeyByPBEWithSHA1AndRC2_40()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithSHA1AndRC2_40";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(secretKey);// com.sun.crypto.provider.PBEKey@d1555e83}
@Test@DisplayName("生成密钥,使用 PBEWithSHA1AndRC2_128")publicvoidGenerateSecretKeyByPBEWithSHA1AndRC2_128()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithSHA1AndRC2_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithSHA1AndRC4_128")publicvoidGenerateSecretKeyByPBEWithSHA1AndRC4_128()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithSHA1AndRC4_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA1AndAES_128")publicvoidGenerateSecretKeyByPBEWithHmacSHA1AndAES_128()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA1AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA224AndAES_128")publicvoidGenerateSecretKeyByPBEWithHmacSHA1AndAES_128()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA224AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA256AndAES_128")publicvoidGenerateSecretKeyByPBEWithHmacSHA256AndAES_128()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA256AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA384AndAES_128")publicvoidGenerateSecretKeyByPBEWithHmacSHA384AndAES_128()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA384AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 P1BEWithHmacSHA1AndAES_256")publicvoidGenerateSecretKeyByPBEWithHmacSHA1AndAES_256()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA1AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA512AndAES_128")publicvoidGenerateSecretKeyByPPBEWithHmacSHA512AndAES_128()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA512AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA224AndAES_256")publicvoidGenerateSecretKeyByPBEWithHmacSHA224AndAES_256()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA224AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA256AndAES_256")publicvoidGenerateSecretKeyByPBEWithHmacSHA256AndAES_256()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA256AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA384AndAES_256")publicvoidGenerateSecretKeyByPBEWithHmacSHA384AndAES_256()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA384AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
@Test@DisplayName("生成密钥,使用 PBEWithHmacSHA512AndAES_256")publicvoidGenerateSecretKeyByPBEWithHmacSHA512AndAES_256()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBEWithHmacSHA512AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));//[49, 50, 51, 52, 53, 54, 55, 56, 57]}
PBK
@Test@DisplayName("生成密钥,使用 PBKDF2WithHmacSHA1")publicvoidGenerateSecretKeyByPBKDF2WithHmacSHA1()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBKDF2WithHmacSHA1";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;int keyLength =512;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount,keyLength);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));}
@Test@DisplayName("生成密钥,使用 PBKDF2WithHmacSHA224")publicvoidGenerateSecretKeyByPBKDF2WithHmacSHA224()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBKDF2WithHmacSHA224";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;int keyLength =512;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount,keyLength);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));}
@Test@DisplayName("生成密钥,使用 PBKDF2WithHmacSHA256")publicvoidGenerateSecretKeyByPBKDF2WithHmacSHA256()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBKDF2WithHmacSHA256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;int keyLength =512;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount,keyLength);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));}
@Test@DisplayName("生成密钥,使用 PBKDF2WithHmacSHA384")publicvoidGenerateSecretKeyByPBKDF2WithHmacSHA384()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBKDF2WithHmacSHA384";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;int keyLength =512;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount,keyLength);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));}
@Test@DisplayName("生成密钥,使用 PBKDF2WithHmacSHA512")publicvoidGenerateSecretKeyByPBKDF2WithHmacSHA512()throwsInvalidKeySpecException,NoSuchAlgorithmException{String algorithm ="PBKDF2WithHmacSHA512";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;int keyLength =512;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount,keyLength);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);System.out.println(Arrays.toString(secretKey.getEncoded()));}
DeSede
@Test@DisplayName("生成 DeSede 算法那使用的 SecretKey")publicvoidgenerateDESedeSecretKey()throwsInvalidKeySpecException,NoSuchAlgorithmException,InvalidKeyException{// 长度不得小于24String userKey ="123456789012345678901234";DESedeKeySpec deSedeKeySpec =newDESedeKeySpec(userKey.getBytes(StandardCharsets.UTF_8));SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance("Desede");SecretKey secretKey = secretKeyFactory.generateSecret(deSedeKeySpec);}
看到了么,这个工厂方法
generateSecret()
极度通用,你需要告诉我秘钥规范就行,我就能给秘钥。
说说秘钥
Key
Key
是Java世界里对算法秘钥对象的抽象,主要抽象了三种行为。
getEncoded
返回主编码格式的键,如果该键不支持编码,则返回NULL。
@Test@DisplayName("秘钥值")publicvoidgetEncoded()throwsNoSuchAlgorithmException{KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(AsymmetricAlgorithm.RSA.getValue());KeyPair keyPair = keyPairGenerator.generateKeyPair();PrivateKey privateKey = keyPair.getPrivate();byte[] encoded = privateKey.getEncoded();System.out.println(encoded.length);// 1792}
getFormat
@Test@DisplayName("返回该键的主要编码格式的名称")publicvoidgetFormat()throwsNoSuchAlgorithmException{String algorithm =AsymmetricAlgorithm.RSA.getValue();KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);KeyPair keyPair = keyPairGenerator.generateKeyPair();PrivateKey privateKey = keyPair.getPrivate();String format = privateKey.getFormat();System.out.println(format);PublicKey publicKey = keyPair.getPublic();String format1 = publicKey.getFormat();System.out.println(format1);/**
* PKCS#8
* X.509
*/}
KeySpec
主要是说制作Key需要的原材料对象。我们按照算法分类,非对称,对称,摘要加密来分类如果构建对应Key时需要的原材料。
- 非对称(以RSA举例)
PKCS8EncodedKey
@Test@DisplayName("创建PKCS8EncodedKeySpec对象")publicvoidPKCS8EncodedKeySpecNew()throwsNoSuchAlgorithmException,InvalidKeySpecException{String algorithm =AsymmetricAlgorithm.RSA.getValue();KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);KeyPair keyPair = keyPairGenerator.generateKeyPair();PrivateKey privateKey = keyPair.getPrivate();//使用私钥对象的编码值来创建byte[] privateKeyEncoded = privateKey.getEncoded();PKCS8EncodedKeySpec pkcs8EncodedKeySpec =newPKCS8EncodedKeySpec(privateKeyEncoded);}
X509EncodedKeySpec
@Test@DisplayName("创建X509EncodedKeySpec对象")publicvoidX509EncodedKeySpecNew()throwsNoSuchAlgorithmException,InvalidKeySpecException{String algorithm =AsymmetricAlgorithm.RSA.getValue();KeyPairGenerator keyPairGenerator =KeyPairGenerator.getInstance(algorithm);KeyPair keyPair = keyPairGenerator.generateKeyPair();PublicKey publicKey = keyPair.getPublic();//使用公钥对象的编码值来创建byte[] publicKeyEncoded = publicKey.getEncoded();X509EncodedKeySpec x509EncodedKeySpec =newX509EncodedKeySpec(publicKeyEncoded);}
- 对称加密(以DES DESede PEB AES RC2 ARCFOUR Blowfish SM4 举例,代码按此序)
@Test@DisplayName("创建DESKeySpec对象")publicvoidDESKeySpecNew()throwsNoSuchAlgorithmException,InvalidKeyException{String algorithm ="DES";String key ="123456";SecretKeySpec secretKeySpec =newSecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);}
@Test@DisplayName("创建DESedeKeySpec对象")publicvoidDESedeKeySpecNew()throwsNoSuchAlgorithmException,InvalidKeyException{String algorithm ="DESede";String key ="123456";SecretKeySpec secretKeySpec =newSecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);System.out.println(secretKeySpec);// javax.crypto.spec.SecretKeySpec@b069b142}
@Test@DisplayName("创建PBEKeySpec对象")publicvoidPBEKeySpecNew()throwsNoSuchAlgorithmException,InvalidKeyException{// 密码char[] password ="123456".toCharArray();//盐SecureRandom random =newSecureRandom();byte[] salt = random.generateSeed(8);//迭代次数int iterationCount =10;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);}
@Test@DisplayName("创建AesKeySpec对象")publicvoidAesKeySpecNew(){String key ="123456";String algorithm ="AES";SecretKeySpec secretKeySpec =newSecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);System.out.println(secretKeySpec);// javax.crypto.spec.SecretKeySpec@17bd9}
@Test@DisplayName("创建RC2KeySpec对象")publicvoidRC2KeySpecNew(){String key ="123456";String algorithm ="RC2";SecretKeySpec secretKeySpec =newSecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);System.out.println(secretKeySpec);// javax.crypto.spec.SecretKeySpec@17bd9}
@Test@DisplayName("创建 ARCFOURKeySpec 对象")publicvoidARCFOURKeySpecNew(){String key ="123456";String algorithm ="ARCFOUR";SecretKeySpec secretKeySpec =newSecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);System.out.println(secretKeySpec);// javax.crypto.spec.SecretKeySpec@17bd9}
@Test@DisplayName("创建 BlowfishKeySpec 对象")publicvoidBlowfishKeySpecNew(){String key ="123456";String algorithm ="Blowfish";SecretKeySpec secretKeySpec =newSecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);System.out.println(secretKeySpec);// javax.crypto.spec.SecretKeySpec@d97afe1c}
@Test@DisplayName("创建 SM4KeySpec 对象")publicvoidSM4KeySpecNew(){Security.addProvider(newBouncyCastleProvider());String key ="123456";String algorithm ="SM4";SecretKeySpec secretKeySpec =newSecretKeySpec(key.getBytes(StandardCharsets.UTF_8), algorithm);System.out.println(secretKeySpec);// javax.crypto.spec.SecretKeySpec@1be0c}
- 摘要Hash加密(以HmacMD5举例)
@Test@DisplayName("创建 HmacMD5KeySpec 对象")publicvoidHmacMD5SpecNew(){String useKey ="123456789";String algorithm ="HmacMD5";SecretKey secretKey =newSecretKeySpec(useKey.getBytes(), algorithm);}
IvParameterSpec
在了解下文的加密模式后,你就知道Java为啥设计这么一个类表示初始化向量了。
@Test@DisplayName("根据 initVector 创建IV参数规范 ")publicvoidIvParameterSpecNew(){// 必须 16 位byte[] initVector ="1234567812345wnx".getBytes(StandardCharsets.UTF_8);IvParameterSpec iv =newIvParameterSpec(initVector);}
RC2ParameterSpec
@Test@DisplayName("根据 rc2ParameterSpec 创建RC2 参数规范 ")publicvoidRC2ParameterSpecNew(){int effectiveKeyBits =100;RC2ParameterSpec rc2ParameterSpec =newRC2ParameterSpec(effectiveKeyBits);}
PBEParameterSpec
@Test@DisplayName("根据盐 和 迭代次数 创建PBE参数规范 ")publicvoidPBEParameterSpecNew(){SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEParameterSpec pbeParameterSpec =newPBEParameterSpec(salt,iterationCount);}
加解密
java安全框架,封装了一个对象Cipher来做这些具体加解密工作。可以说是整个安全体系框架的核心类了。我们只需要告诉Java,算法名,就能创建出Cipher对象啦,比如下面这样。
@Test@DisplayName("根据RSA算法获取Cipher对象")publicvoidgetInstance()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeySpecException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException{String algorithm =AsymmetricAlgorithm.RSA.getValue();Cipher cipher =Cipher.getInstance(algorithm);}
The following names can be specified as the algorithm component in a transformation when requesting an instance of
Cipher
. 在请求Cipher实例时,可以将以下名称指定为转换中的算法组件。(摘抄于JDK文档)
填充模式
在真正做加解密工作之前,我们还需要了解填充模式。数据长度在实际中并不是一定符合算法本身设置的长度字节。当需要按块处理的数据,数据长度不符合块处理需求时,会按照一定的方法填充块长的规则。
来看下Java支持的填充模式。
某些加密算法要求明文需要按一定长度对齐,叫做块大小(
BlockSize
),比如16字节,那么对于一段任意的数据,加密前需要对最后一个块填充到16 字节,解密后需要删除掉填充的数据。
ZeroPadding
,数据长度不对齐时使用0填充,否则不填充。
PKCS7Padding
,假设数据长度需要填充n(n>0)个字节才对齐,那么填充n个字节,每个字节都是n;如果数据本身就已经对齐了,则填充一块长度为块大小的数据,每个字节都是块大小。
PKCS5Padding,PKCS7Padding的子集,块大小固定为8字节。
由于使用PKCS7Padding/PKCS5Padding填充时,最后一个字节肯定为填充数据的长度,所以在解密后可以准确删除填充的数据,而使用
ZeroPadding
填充时,没办法区分真实数据与填充数据,所以只适合以\0结尾的字符串加解密。
- 1、
NoPadding
不填充
因为不填充,所以对标DES加密算法中,要求原文必须是8byte的整数倍,对标AES加密算法中,要求原文必须是16byte的整数倍。
- 2、
ZeroPadding
(Java没有)
而Java中又不提供
ZeroPadding
,我们在使用
NoPadding
填充时,当最后一个块不是
8 byte
或者
16 byte
字节时,我们就要对原文进行自行填充。据说C# 有这个
ZeroPadding
填充0.
在解密时,再删除掉填充的数据。
- 3、PKCS5Padding
数据块的大小为8位,不够就补足8位。
- Java中,默认情况下,加密模式和填充模式为:ECB/PKCS5Padding
- 如果要使用 CBC 模式,在初始化 Cipher对象时,需要添加参数,初始化向量
IV
IvParameterSpec iv = IvParameterSpec(byte[] iv)
加密算法模式
he following names can be specified as the mode component in a transformation when requesting an instance of
Cipher
. JDK8支持的加密算法模式,可以将以下名称指定为[转换]中的模式组件.(摘抄于JDK官方文档)
可以将以下名称指定为[转换]中的模式组件
这里简单说一下加密算法模式,不要把它与加密算法混淆起来,加密算法就是使用何种方式加密,比如:DES、AES、RSA,而加密算法模式,是用来描述加密算法(此处特指分组密码,不包括流密码,)在加密时对明文分组的模式,它代表了不同的分组方式,如常见的:
ECB模式:电子密码本模式
CBC模式:密码分组连接模式
CBC模式在对明文分组加密时,会将明文分组与前一个密文分组进行XOR运算(即异或运算),但是加密第一个明文分组时不存在“前一个密文分组”,因此需要事先准备一个与分组长度相等的比特序列来代替,这个比特序列就是偏移量。(见网络工程师教程一书)
在Java中,会把这向量 抽象成
IvParameterSpec
CFB模式:密文反馈模式
OFB模式:输出反馈模式
CTR模式:计数器模式
在了解了填充模式和加密算法模式之后,我们从对称、非对称、摘要(Hash)三个角度开始,来做加解密工作。
- 1、非对称
RSA
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importorg.springframework.util.Base64Utils;importjavax.crypto.BadPaddingException;importjavax.crypto.Cipher;importjavax.crypto.IllegalBlockSizeException;importjavax.crypto.NoSuchPaddingException;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.security.spec.PKCS8EncodedKeySpec;importjava.security.spec.X509EncodedKeySpec;publicclassCipherTest{String privateKeyStr ="MIICdwIBADANBgkqhkiG9....";String publicKeyStr ="MIGfMA0GCSqGSIb3DQEBAQUA..";@Test@DisplayName("公钥加密 私钥解密")publicvoidpublicEncUsePriDen()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeySpecException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException{String transformation ="RSA";Cipher cipher =Cipher.getInstance(transformation);String algorithm ="RSA";KeyFactory keyFactory =KeyFactory.getInstance(algorithm);X509EncodedKeySpec x509EncodedKeySpec =newX509EncodedKeySpec(Base64Utils.decode(publicKeyStr.getBytes()));PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);PKCS8EncodedKeySpec pkcs8EncodedKeySpec =newPKCS8EncodedKeySpec(Base64Utils.decode(privateKeyStr.getBytes()));PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes());String result =Base64Utils.encodeToString(secret);System.out.println("加密:"+ result);
cipher.init(Cipher.DECRYPT_MODE,privateKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));}@Test@DisplayName("私钥加密 公钥解密(验签)")publicvoidpriEncUsePublicDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeySpecException,IllegalBlockSizeException,BadPaddingException,InvalidKeyException{String transformation ="RSA";Cipher cipher =Cipher.getInstance(transformation);String algorithm ="RSA";KeyFactory keyFactory =KeyFactory.getInstance(algorithm);X509EncodedKeySpec x509EncodedKeySpec =newX509EncodedKeySpec(Base64Utils.decode(publicKeyStr.getBytes()));PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);PKCS8EncodedKeySpec pkcs8EncodedKeySpec =newPKCS8EncodedKeySpec(Base64Utils.decode(privateKeyStr.getBytes()));PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes());String result =Base64Utils.encodeToString(secret);System.out.println("加密:"+ result);
cipher.init(Cipher.DECRYPT_MODE,publicKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));}}
- 2、对称
AES
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.SecretKeySpec;importjava.io.UnsupportedEncodingException;importjava.nio.charset.StandardCharsets;importjava.security.InvalidKeyException;importjava.security.Key;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;publicclassCipherTest{@Test@DisplayName("处理AES加密 解密")publicvoidaesEncryptAndDecrypt()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,UnsupportedEncodingException,IllegalBlockSizeException,BadPaddingException,InvalidKeyException{String source ="12346";// 这里的userKey 其实就是 SecureRandom 的种子 基于该种子 会得到一个16 位的秘钥 secretKeyString userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="AES";KeyGenerator generator =KeyGenerator.getInstance(algorithm);
generator.init(secureRandom);Key secretKey = generator.generateKey();String transformation ="AES/ECB/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:SMQHFyeAwWnGyjv4qjD3/Q==
* 解密结果:12346
*/}@Test@DisplayName("同样也是AES加密 只是秘钥的生成方式不同 ")publicvoidaesEncryptGetSecretKeyDifferent()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException{String source ="12346";// 这里的userKey 就是 秘钥 secretKey AES 规定了必须是16位!String userKey ="wangnaixing@spri";System.out.println(userKey.length());String algorithm ="AES";SecretKey secretKey =newSecretKeySpec(userKey.getBytes(StandardCharsets.UTF_8),
algorithm);String transformation ="AES/ECB/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 16
* 加密结果:7nLgfZNZc1N8o4ApjUJlpQ==
* 解密结果:12346
*/}}
AES/CBC/NoPadding
packagecom.wnx.naizi;importcn.hutool.core.util.StrUtil;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.IvParameterSpec;importjava.io.UnsupportedEncodingException;importjava.nio.charset.StandardCharsets;importjava.security.*;/**
* @ClassName: AESTest
* @Package: com.wnx.naizi
* @Description:
* @Author: wangnaixing
* @Create: 2022/12/22 - 22:33
* @Version:v1.0
*/publicclassAESTest{@Test@DisplayName("AES/CBC/NoPadding")publicvoidNoPadding()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,UnsupportedEncodingException,IllegalBlockSizeException,BadPaddingException,InvalidKeyException,InvalidKeyException,InvalidAlgorithmParameterException{String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="AES";KeyGenerator generator =KeyGenerator.getInstance(algorithm);
generator.init(secureRandom);Key secretKey = generator.generateKey();String transformation ="AES/CBC/NoPadding";Cipher cipher =Cipher.getInstance(transformation);int blockSize = cipher.getBlockSize();String source ="12346";// 因为原加密数据 最后一个数据块 不够16个字节 而Java原生没有ZeroPadding模式,所以手动构建 ZeroPaddingbyte[] dataBytes = source.getBytes();int length = dataBytes.length;if(length % blockSize !=0){
length = length +(blockSize -(length % blockSize));}byte[] plaintext =newbyte[length];System.arraycopy(dataBytes,0, plaintext,0, dataBytes.length);byte[] iv ="0000000000000000".getBytes();IvParameterSpec ivSpec =newIvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKey,ivSpec);byte[] secret = cipher.doFinal(plaintext);String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE,secretKey,ivSpec);byte[] bytes = cipher.doFinal(secret);// 所以在解密后可以准确删除填充的数据System.out.println("解密结果:"+StrUtil.trimEnd(newString(bytes)));/**
* 加密结果:SMQHFyeAwWnGyjv4qjD3/Q==
* 解密结果:12346
*/}}
AES/ECB/PKCS5Padding
@Test@DisplayName("AES/ECB/PKCS5Padding")publicvoidtransformationUseOne()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,UnsupportedEncodingException,IllegalBlockSizeException,BadPaddingException,InvalidKeyException{String source ="12346";// 这里的userKey 其实就是 SecureRandom 的种子 基于该种子 会得到一个16 位的秘钥 secretKeyString userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="AES";KeyGenerator generator =KeyGenerator.getInstance(algorithm);
generator.init(secureRandom);Key secretKey = generator.generateKey();String transformation ="AES/ECB/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:SMQHFyeAwWnGyjv4qjD3/Q==
* 解密结果:12346
*/}
AES/CBC/PKCS7Padding
@Test@DisplayName("AES/CBC/PKCS7Padding")publicvoidtransformationUseTwo()throwsNoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidAlgorithmParameterException{String source ="12346";// 这里的userKey 其实就是 SecureRandom 的种子 基于该种子 会得到一个16 位的秘钥 secretKeyString userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="AES";KeyGenerator generator =KeyGenerator.getInstance(algorithm);
generator.init(secureRandom);Key secretKey = generator.generateKey();// 要添加 算法提供者Security.addProvider(newBouncyCastleProvider());String transformation ="AES/CBC/PKCS7Padding";Cipher cipher =Cipher.getInstance(transformation);// 16 位 ivbyte[] initVector ="1234567812345678".getBytes(StandardCharsets.UTF_8);IvParameterSpec iv =newIvParameterSpec(initVector);
cipher.init(Cipher.ENCRYPT_MODE, secretKey,iv);byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,iv);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
*加密结果:nJdZblr0zrdY4CugGkrwiA==
* 解密结果:12346
*/}
JDK没有提供 AES/CBC/PKCS7Padding 填充算法,需要导入包。
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk16</artifactId><version>1.46</version></dependency>
AES/CBC/PKCS5Padding
@Test@DisplayName("AES/CBC/PKCS5Padding")publicvoidtransformationUseThree()throwsNoSuchPaddingException,NoSuchAlgorithmException,IllegalBlockSizeException,BadPaddingException,InvalidKeyException,InvalidAlgorithmParameterException{String source ="12346";// 这里的userKey 其实就是 SecureRandom 的种子 基于该种子 会得到一个16 位的秘钥 secretKeyString userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="AES";KeyGenerator generator =KeyGenerator.getInstance(algorithm);
generator.init(secureRandom);Key secretKey = generator.generateKey();// 16 位 ivbyte[] initVector ="1234567812345678".getBytes(StandardCharsets.UTF_8);IvParameterSpec iv =newIvParameterSpec(initVector);String transformation ="AES/CBC/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE, secretKey,iv);byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,iv);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:nJdZblr0zrdY4CugGkrwiA==
* 解密结果:12346
*/}
AES/ECB/NoPadding
我前面说了,Java没有实现NoPadding模式,所以这里我简单实现了下。
packagecom.wnx.naizi;importcn.hutool.core.util.StrUtil;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjava.io.UnsupportedEncodingException;importjava.nio.charset.StandardCharsets;importjava.security.*;/**
* @ClassName: AESTest
* @Package: com.wnx.naizi
* @Description:
* @Author: wangnaixing
* @Create: 2022/12/25 - 15:16
* @Version:v1.0
*/publicclassAESTest{@Test@DisplayName("AES/ECB/NoPadding")publicvoidNoPadding()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,UnsupportedEncodingException,IllegalBlockSizeException,BadPaddingException,InvalidKeyException,InvalidKeyException,InvalidAlgorithmParameterException,InvalidKeyException{String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="AES";KeyGenerator generator =KeyGenerator.getInstance(algorithm);
generator.init(secureRandom);Key secretKey = generator.generateKey();String transformation ="AES/ECB/NoPadding";Cipher cipher =Cipher.getInstance(transformation);int blockSize = cipher.getBlockSize();String source ="12346";// 因为原加密数据 最后一个数据块 不够16个字节 而Java原生没有ZeroPadding模式,所以手动构建 ZeroPaddingbyte[] dataBytes = source.getBytes();int length = dataBytes.length;if(length % blockSize !=0){
length = length +(blockSize -(length % blockSize));}byte[] plaintext =newbyte[length];System.arraycopy(dataBytes,0, plaintext,0, dataBytes.length);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] secret = cipher.doFinal(plaintext);String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);// 所以在解密后可以准确删除填充的数据System.out.println("解密结果:"+StrUtil.trimEnd(newString(bytes)));/**
* 加密结果:lxhdLy677lKdtRdavV98XA==
* 解密结果:12346
*/}}
DES
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.DESKeySpec;importjavax.crypto.spec.IvParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassDESTest{@Test@DisplayName("处理DES加密 解密")publicvoiddesEncryptAndDecrypt()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException{String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="DES";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);
keyGenerator.init(secureRandom);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DES";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:ETre2lTFFzk=
* 解密结果:123456
*/}@Test@DisplayName("同样也是DES加解密 只是秘钥的生成方式不同 ")publicvoiddesEncryptGetSecretKeyDifferent()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException{// -_- 这里老哥要把userKey 必须64 位String userKey ="gkalgksdngskadng12123456789123456789qwertyuiojsacgafgdasfs123456";DESKeySpec desKeySpec =newDESKeySpec(userKey.getBytes(StandardCharsets.UTF_8));String algorithm ="DES";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);String transformation ="DES";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:RGGFISTk82I=
* 解密结果:123456
*
*/}@Test@DisplayName("这种方式 是在第一种方式 上不要 SecureRandom ")publicvoiddesEncryptAndDecryptEasyWay()throwsNoSuchAlgorithmException,NoSuchPaddingException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException{String algorithm ="DES";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DES";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:W598cif2Xkg=
* 解密结果:123456
*/}}
DES/ECB/PKCS5Padding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.DESKeySpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassDESTest{@Test@DisplayName("DES/ECB/PKCS5Padding")publicvoidjdkDESEncryptAndDecrypt()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException{// -_- 必须64 位String userKey ="gkalgksdngskadng12123456789123456789qwertyuiojsacgafgdasfs123456";DESKeySpec desKeySpec =newDESKeySpec(userKey.getBytes(StandardCharsets.UTF_8));String algorithm ="DES";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);String transformation ="DES/ECB/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:RGGFISTk82I=
* 解密结果:123456
*/}}
DES/ECB/NoPadding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjava.nio.charset.StandardCharsets;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;/**
* @ClassName: DESTest
* @Package: com.wnx.naizi
* @Description:
* @Author: wangnaixing
* @Create: 2022/12/25 - 15:21
* @Version:v1.0
*/publicclassDESTest{@Test@DisplayName("DES/ECB/NoPadding")publicvoidjdkDESEncryptAndDecrypt()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidKeyException{String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="DES";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);
keyGenerator.init(secureRandom);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DES/ECB/NoPadding";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";// 因为原加密数据 最后一个数据块 不够16个字节 而Java原生没有ZeroPadding模式,所以手动构建 ZeroPaddingbyte[] dataBytes = source.getBytes();int blockSize = cipher.getBlockSize();int length = dataBytes.length;if(length % blockSize !=0){
length = length +(blockSize -(length % blockSize));}byte[] plaintext =newbyte[length];System.arraycopy(dataBytes,0, plaintext,0, dataBytes.length);byte[] secret = cipher.doFinal(plaintext);String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes).trim());/**
* 加密结果:zH+BB+piRC4=
* 解密结果:123456
*/}}
DES/CBC/PKCS5Padding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.DESKeySpec;importjavax.crypto.spec.IvParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassDESTest{@Test@DisplayName("DES/CBC/PKCS5Padding")publicvoidjdkDESEncryptAndDecrypt()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{// -_- 必须64 位String userKey ="gkalgksdngskadng12123456789123456789qwertyuiojsacgafgdasfs123456";DESKeySpec desKeySpec =newDESKeySpec(userKey.getBytes(StandardCharsets.UTF_8));String algorithm ="DES";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);String transformation ="DES/CBC/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);byte[] initVector ="12345678".getBytes(StandardCharsets.UTF_8);IvParameterSpec ivParameterSpec =newIvParameterSpec(initVector);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,ivParameterSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,ivParameterSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:V67A54IaVYs=
* 解密结果:123456
*/}}
DES/CBC/NoPadding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.DESKeySpec;importjavax.crypto.spec.IvParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassDESTest{@Test@DisplayName("DES/CBC/NoPadding")publicvoidjdkDESEncryptAndDecrypt()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{// -_- 必须64 位String userKey ="gkalgksdngskadng12123456789123456789qwertyuiojsacgafgdasfs123456";DESKeySpec desKeySpec =newDESKeySpec(userKey.getBytes(StandardCharsets.UTF_8));String algorithm ="DES";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);SecretKey secretKey = secretKeyFactory.generateSecret(desKeySpec);String transformation ="DES/CBC/NoPadding";Cipher cipher =Cipher.getInstance(transformation);byte[] initVector ="12345678".getBytes(StandardCharsets.UTF_8);IvParameterSpec ivParameterSpec =newIvParameterSpec(initVector);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,ivParameterSpec);String source ="123456";// 因为原加密数据 最后一个数据块 不够16个字节 而Java原生没有ZeroPadding模式,所以手动构建 ZeroPaddingbyte[] dataBytes = source.getBytes();int blockSize = cipher.getBlockSize();int length = dataBytes.length;if(length % blockSize !=0){
length = length +(blockSize -(length % blockSize));}byte[] plaintext =newbyte[length];System.arraycopy(dataBytes,0, plaintext,0, dataBytes.length);byte[] secret = cipher.doFinal(plaintext);String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,ivParameterSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes).trim());/**
* 加密结果:pWsGRue5FIA=
* 解密结果:123456
*/}}
PBE
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBE")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBE";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,paramSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:pbpGHf1eAuU=
* 解密结果:123456
*/}}
PBEWithMD5AndDES
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithMD5AndDES")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithMD5AndDES";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,paramSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:WWvGlGx5z84=
* 解密结果:123456
*/}}
PBEWithSHA1AndDESede
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithSHA1AndDESede")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithSHA1AndDESede";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,paramSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:BpTTjxVYaDw=
* 解密结果:123456
*/}}
PBEWithSHA1AndRC2_40
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithSHA1AndRC2_40")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithSHA1AndRC2_40";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,paramSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:IlByzM0MQx4=
* 解密结果:123456
*/}}
PBEWithMD5AndTripleDES
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithMD5AndTripleDES")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithMD5AndTripleDES";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,paramSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:6kTTkaCn7xQ=
* 解密结果:123456
*/}}
PBEWithSHA1AndRC2_128
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithSHA1AndRC2_128")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithSHA1AndRC2_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,paramSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:vWqmRZ8BZg8=
* 解密结果:123456
*/}}
PBEWithSHA1AndRC4_128
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.SecureRandom;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithSHA1AndRC4_128")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithSHA1AndRC4_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);
cipher.init(Cipher.DECRYPT_MODE, secretKey,paramSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:lgNsc9iN
* 解密结果:123456
*/}}
PBEWithHmacSHA1AndAES_128
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA1AndAES_128")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA1AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:hcJRhzKDSoCjRBEf0/SlEg==
* 解密结果:123456
*/}}
PBEWithHmacSHA224AndAES_128
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA224AndAES_128")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{String algorithm ="PBEWithHmacSHA224AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:m3aALkbg9M0Av9oV+jedKg==
* 解密结果:123456
*/}}
PBEWithHmacSHA256AndAES_128
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA256AndAES_128")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA256AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:Uk2jRr3iyECZMOnANSSsVg==
* 解密结果:123456
*/}}
PBEWithHmacSHA384AndAES_128
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA384AndAES_128")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA384AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
*加密结果:g99k4wqnthUCrKa/6QJPew==
* 解密结果:123456
*/}}
PBEWithHmacSHA512AndAES_128
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA512AndAES_128")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA512AndAES_128";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
*加密结果:ofMXTUZ57bn1SsMnIgKgzg==
* 解密结果:123456
*/}}
PBEWithHmacSHA1AndAES_256
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA1AndAES_256")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA1AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
*加密结果:ULXyMseR+YKB1KaEodYNxQ==
* 解密结果:123456
*/}}
PBEWithHmacSHA224AndAES_256
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA224AndAES_256")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA224AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
*加密结果:0hPDeiJOch94aDM5vco3ew==
* 解密结果:123456
*/}}
PBEWithHmacSHA256AndAES_256
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA256AndAES_256")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA256AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
*加密结果:2yWWMVzgW1fb8IHV6p7P1w==
* 解密结果:123456
*/}}
PBEWithHmacSHA384AndAES_256
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA384AndAES_256")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA384AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
*加密结果:bvRQ/vO1IuEPpjHEycko9w==
* 解密结果:123456
*/}}
PBEWithHmacSHA512AndAES_256
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.PBEKeySpec;importjavax.crypto.spec.PBEParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.*;importjava.security.spec.InvalidKeySpecException;importjava.util.Base64;publicclassPBETest{@Test@DisplayName("PBEWithHmacSHA512AndAES_256")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{;String algorithm ="PBEWithHmacSHA512AndAES_256";SecretKeyFactory secretKeyFactory =SecretKeyFactory.getInstance(algorithm);char[] password ="123456789".toCharArray();SecureRandom secureRandom =newSecureRandom();byte[] salt = secureRandom.generateSeed(8);int iterationCount =1000;PBEKeySpec pbeKeySpec =newPBEKeySpec(password,salt,iterationCount);SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);Cipher cipher =Cipher.getInstance(algorithm);PBEParameterSpec paramSpec =newPBEParameterSpec(salt, iterationCount);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//注意解密!!! parametersAlgorithmParameters parameters = cipher.getParameters();
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameters);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:ec6c9KEIpjUBZwobjIzROw==
* 解密结果:123456
*/}}
RC2
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.RC2ParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;publicclassCipherTest{@Test@DisplayName("RC2加解密")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{String algorithm ="RC2";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();Cipher cipher =Cipher.getInstance(algorithm);int effectiveKeyBits =100;RC2ParameterSpec paramSpec =newRC2ParameterSpec(effectiveKeyBits);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,paramSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,paramSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:yK8QyeMoJeI=
* 解密结果:123456
*/}}
ARCFOUR
@Test@DisplayName("ARCFOUR 加解密")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{String algorithm ="ARCFOUR";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();Cipher cipher =Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:dDFC2dKK
* 解密结果:123456
*/}
Blowfish
@Test@DisplayName("Blowfish 加解密")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{String algorithm ="Blowfish";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();Cipher cipher =Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:i1JrLW+fD3U=
* 解密结果:123456
*
*/}
SM4
@Test@DisplayName("SM4 加解密")publicvoidencAndDec()throwsNoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException,NoSuchProviderException,NoSuchPaddingException{Security.addProvider(newBouncyCastleProvider());String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="SM4";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm,BouncyCastleProvider.PROVIDER_NAME);
keyGenerator.init(newSecureRandom());SecretKey secretKey = keyGenerator.generateKey();String transformation ="SM4";Cipher cipher =Cipher.getInstance(transformation);// 16 位byte[] iv ="123456789ABCDEFG".getBytes(StandardCharsets.UTF_8);IvParameterSpec ivParameterSpec =newIvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,ivParameterSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,ivParameterSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:yogRcYocEVAjkN0L5RiFbA==
* 解密结果:123456
*/}
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on --><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version></dependency>
SM4/CBC/PKCS5Padding
@Test@DisplayName("SM4/CBC/PKCS5Padding")publicvoidencAndDec()throwsNoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException,NoSuchProviderException,NoSuchPaddingException{Security.addProvider(newBouncyCastleProvider());String userKey ="wangnaixing@springBoot";String randomAlgorithm ="SHA1PRNG";SecureRandom secureRandom =SecureRandom.getInstance(randomAlgorithm);byte[] seed = userKey.getBytes(StandardCharsets.UTF_8);
secureRandom.setSeed(seed);String algorithm ="SM4";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm,BouncyCastleProvider.PROVIDER_NAME);
keyGenerator.init(newSecureRandom());SecretKey secretKey = keyGenerator.generateKey();String transformation ="SM4/CBC/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);// 16 位byte[] iv ="123456789ABCDEFG".getBytes(StandardCharsets.UTF_8);IvParameterSpec ivParameterSpec =newIvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,ivParameterSpec);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,ivParameterSpec);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:8Zn7KIOM/0fy9FjfPIffGg==
* 解密结果:123456
*/}
<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on --><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.70</version></dependency>
RC4
packagecom.wnx.naizi;importorg.bouncycastle.jce.provider.BouncyCastleProvider;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.Security;importjava.security.spec.InvalidKeySpecException;publicclassCipherTest{@Test@DisplayName("RC4加解密")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{Security.addProvider(newBouncyCastleProvider());String algorithm ="RC4";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();Cipher cipher =Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:aLylwNlT
* 解密结果:123456
*/}}
<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk16</artifactId><version>1.46</version></dependency>
DESede
@Test@DisplayName("DESede 加解密")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();Cipher cipher =Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:oYqOmjrHMH8=
* 解密结果:123456
*/}
DESede/OFB/PKCS5Padding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.IvParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;publicclassCipherTest{@Test@DisplayName("DESede/OFB/PKCS5Padding")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DESede/OFB/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);// must be 8 bytes longbyte[] initVector ="12345678".getBytes(StandardCharsets.UTF_8);IvParameterSpec iv =newIvParameterSpec(initVector);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,iv);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,iv);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:HAN6bHtDo08=
* 解密结果:123456
*/}}
DESede/CBC/PKCS5Padding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.IvParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;publicclassCipherTest{@Test@DisplayName("DESede/CBC/PKCS5Padding")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DESede/CBC/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);// must be 8 bytes longbyte[] initVector ="12345678".getBytes(StandardCharsets.UTF_8);IvParameterSpec iv =newIvParameterSpec(initVector);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,iv);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,iv);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:C+fJqYMVNqQ=
* 解密结果:123456
*/}}
DESede/CFB/PKCS5Padding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.IvParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;publicclassCipherTest{@Test@DisplayName("DESede/CFB/PKCS5Padding")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DESede/CFB/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);// must be 8 bytes longbyte[] initVector ="12345678".getBytes(StandardCharsets.UTF_8);IvParameterSpec iv =newIvParameterSpec(initVector);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,iv);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,iv);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:SIrwcQvmdZE=
* 解密结果:123456
*/}}
DESede/ECB/PKCS5Padding
packagecom.wnx.naizi;importorg.bouncycastle.jce.provider.BouncyCastleProvider;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.Security;importjava.security.spec.InvalidKeySpecException;publicclassCipherTest{@Test@DisplayName("DESede/ECB/PKCS5Padding")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException{Security.addProvider(newBouncyCastleProvider());String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DESede/ECB/PKCS5Padding";Cipher cipher =Cipher.getInstance(transformation);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";byte[] secret = cipher.doFinal(source.getBytes(StandardCharsets.UTF_8));String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes));/**
* 加密结果:ejjVhf1RvTY=
* 解密结果:123456
*/}}
DESede/CBC/NoPadding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjavax.crypto.spec.IvParameterSpec;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;publicclassCipherTest{@Test@DisplayName("DESede/CBC/NoPadding")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException,InvalidKeyException{String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DESede/CBC/NoPadding";Cipher cipher =Cipher.getInstance(transformation);// must be 8 bytes longbyte[] initVector ="12345678".getBytes(StandardCharsets.UTF_8);IvParameterSpec iv =newIvParameterSpec(initVector);
cipher.init(Cipher.ENCRYPT_MODE,secretKey,iv);String source ="123456";int blockSize = cipher.getBlockSize();// 因为原加密数据 最后一个数据块 不够16个字节 而Java原生没有ZeroPadding模式,所以手动构建 ZeroPaddingbyte[] dataBytes = source.getBytes();int length = dataBytes.length;if(length % blockSize !=0){
length = length +(blockSize -(length % blockSize));}byte[] plaintext =newbyte[length];System.arraycopy(dataBytes,0, plaintext,0, dataBytes.length);byte[] secret = cipher.doFinal(plaintext);String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey,iv);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes).trim());/**
* 加密结果:C+fJqYMVNqQ=
* 解密结果:123456
*/}}
DESede/ECB/NoPadding
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjavax.crypto.*;importjava.nio.charset.StandardCharsets;importjava.security.InvalidAlgorithmParameterException;importjava.security.InvalidKeyException;importjava.security.NoSuchAlgorithmException;importjava.security.spec.InvalidKeySpecException;publicclassCipherTest{@Test@DisplayName("DESede/ECB/NoPadding")publicvoidencAndDec()throwsNoSuchPaddingException,NoSuchAlgorithmException,InvalidKeyException,IllegalBlockSizeException,BadPaddingException,InvalidKeySpecException,InvalidAlgorithmParameterException,InvalidKeyException{String algorithm ="DESede";KeyGenerator keyGenerator =KeyGenerator.getInstance(algorithm);SecretKey secretKey = keyGenerator.generateKey();String transformation ="DESede/ECB/NoPadding";Cipher cipher =Cipher.getInstance(transformation);// must be 8 bytes longbyte[] initVector ="12345678".getBytes(StandardCharsets.UTF_8);
cipher.init(Cipher.ENCRYPT_MODE,secretKey);String source ="123456";int blockSize = cipher.getBlockSize();// 因为原加密数据 最后一个数据块 不够16个字节 而Java原生没有ZeroPadding模式,所以手动构建 ZeroPaddingbyte[] dataBytes = source.getBytes();int length = dataBytes.length;if(length % blockSize !=0){
length = length +(blockSize -(length % blockSize));}byte[] plaintext =newbyte[length];System.arraycopy(dataBytes,0, plaintext,0, dataBytes.length);byte[] secret = cipher.doFinal(plaintext);String result =java.util.Base64.getEncoder().encodeToString(secret);System.out.println("加密结果:"+result);//解密
cipher.init(Cipher.DECRYPT_MODE,secretKey);byte[] bytes = cipher.doFinal(secret);System.out.println("解密结果:"+newString(bytes).trim());/**
* 加密结果:qS0TPKndTVc=
* 解密结果:123456
*/}}
- 3、摘要(Hash)
MD5
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("MD5 加密")publicvoidjdkMd5AndEncodeTOBase64()throwsNoSuchAlgorithmException{String algorithm ="MD5";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// 4QrcOUm6Wau+VuBX8g+IPg==}}
MD2
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("MD2 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="MD2";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// 1FQSULWGKW/M5d6kRjrhfw==}}
SHA-1
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("SHA-1 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="SHA-1";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// fEqNCco3Yq9h5ZUglD3CZJT4lBs=}}
SHA-256
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("SHA-256 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="SHA-256";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// jZae727K08KaOmKSgOaGzww/XVqGr/PKEgIMkjrcbJI=}}
SHA-384
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("SHA-384 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="SHA-384";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// CpievEp3tWpuK7exnZldGFzkQJDBPimEt+zG1EbUth6pmRt2pMLwSxtNJEhBRJRU}}
SHA-512
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("SHA-512 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="SHA-512";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// ujJTh2rta8ItSm/1PYQGxq2GQZXtFEq1yHYhtsIztUi66uaVbfNG7IwX9eoQ817jy8UUeX7X3dMUVGTioLq0Ew==}}
au+VuBX8g+IPg==
}
}
## MD2
```java
package com.wnx.naizi;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class CipherTest {
@Test
@DisplayName("MD2 加密")
public void encAndDen() throws NoSuchAlgorithmException {
String algorithm = "MD2";
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
String source = "123456";
byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));
String result = Base64.getEncoder().encodeToString(digest);
System.out.println(result); // 1FQSULWGKW/M5d6kRjrhfw==
}
}
SHA-1
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("SHA-1 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="SHA-1";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// fEqNCco3Yq9h5ZUglD3CZJT4lBs=}}
SHA-256
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("SHA-256 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="SHA-256";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// jZae727K08KaOmKSgOaGzww/XVqGr/PKEgIMkjrcbJI=}}
SHA-384
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("SHA-384 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="SHA-384";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// CpievEp3tWpuK7exnZldGFzkQJDBPimEt+zG1EbUth6pmRt2pMLwSxtNJEhBRJRU}}
SHA-512
packagecom.wnx.naizi;importorg.junit.jupiter.api.DisplayName;importorg.junit.jupiter.api.Test;importjava.nio.charset.StandardCharsets;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;importjava.util.Base64;publicclassCipherTest{@Test@DisplayName("SHA-512 加密")publicvoidencAndDen()throwsNoSuchAlgorithmException{String algorithm ="SHA-512";MessageDigest messageDigest =MessageDigest.getInstance(algorithm);String source ="123456";byte[] digest = messageDigest.digest(source.getBytes(StandardCharsets.UTF_8));String result =Base64.getEncoder().encodeToString(digest);System.out.println(result);// ujJTh2rta8ItSm/1PYQGxq2GQZXtFEq1yHYhtsIztUi66uaVbfNG7IwX9eoQ817jy8UUeX7X3dMUVGTioLq0Ew==}}
版权归原作者 晴城丶 所有, 如有侵权,请联系我们删除。