PemUtil.readPemPrivateKey支持pkcs#1格式,增加OpensslKeyUtil

This commit is contained in:
Looly
2022-07-17 21:26:09 +08:00
parent b6a4be4aab
commit 5ba2ba9e2a
30 changed files with 411 additions and 294 deletions

View File

@@ -1,4 +1,4 @@
package cn.hutool.crypto.test;
package cn.hutool.crypto;
import cn.hutool.crypto.BCUtil;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;

View File

@@ -1,4 +1,4 @@
package cn.hutool.crypto.test;
package cn.hutool.crypto;
import cn.hutool.crypto.CryptoException;
import cn.hutool.crypto.GlobalBouncyCastleProvider;

View File

@@ -0,0 +1,55 @@
package cn.hutool.crypto;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.SM2;
import org.junit.Assert;
import org.junit.Test;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.List;
public class OpensslKeyUtilTest {
@Test
public void verifyPemUtilReadKey() {
// 公钥
// PKCS#10 文件读取公钥
final PublicKey csrPublicKey = (PublicKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_certificate_request.csr"), null);
// 证书读取公钥
final PublicKey certPublicKey = (PublicKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_certificate.cer"), null);
// PEM 公钥
final PublicKey plainPublicKey = (PublicKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_public_key.pem"), null);
// 私钥
// 加密的 PEM 私钥
final PrivateKey encPrivateKey = (PrivateKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_encrypted_private_key.key"), "123456".toCharArray());
// PKCS#8 私钥
final PrivateKey pkcs8PrivateKey = (PrivateKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_pkcs8_private_key.key"), null);
// SEC 1 私钥
final PrivateKey sec1PrivateKey = (PrivateKey) OpensslKeyUtil.readPemKey(ResourceUtil.getStream("test_ec_sec1_private_key.pem"), null);
// 组装还原后的公钥和私钥列表
final List<PublicKey> publicKeyList = Arrays.asList(csrPublicKey, certPublicKey, plainPublicKey);
final List<PrivateKey> privateKeyList = Arrays.asList(encPrivateKey, pkcs8PrivateKey, sec1PrivateKey);
// 做笛卡尔积循环验证
for (final PrivateKey privateKeyItem : privateKeyList) {
for (final PublicKey publicKeyItem : publicKeyList) {
// 校验公私钥
final SM2 genSm2 = new SM2(privateKeyItem, publicKeyItem);
genSm2.usePlainEncoding();
final String content = "我是Hanley.";
final byte[] sign = genSm2.sign(StrUtil.utf8Bytes(content));
final boolean verify = genSm2.verify(StrUtil.utf8Bytes(content), sign);
Assert.assertTrue(verify);
}
}
}
}

View File

@@ -0,0 +1,80 @@
package cn.hutool.crypto;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.SM2;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
public class PemUtilTest {
@Test
public void readPrivateKeyTest() {
final PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_private_key.pem"));
Assert.assertNotNull(privateKey);
}
@Test
public void readPublicKeyTest() {
final PublicKey publicKey = PemUtil.readPemPublicKey(ResourceUtil.getStream("test_public_key.csr"));
Assert.assertNotNull(publicKey);
}
@Test
public void readPemKeyTest() {
final PublicKey publicKey = (PublicKey) PemUtil.readPemKey(ResourceUtil.getStream("test_public_key.csr"));
Assert.assertNotNull(publicKey);
}
@Test
public void validateKey() {
final PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_private_key.pem"));
final PublicKey publicKey = PemUtil.readPemPublicKey(ResourceUtil.getStream("test_public_key.csr"));
final RSA rsa = new RSA(privateKey, publicKey);
final String str = "你好Hutool";//测试字符串
final String encryptStr = rsa.encryptBase64(str, KeyType.PublicKey);
final String decryptStr = rsa.decryptStr(encryptStr, KeyType.PrivateKey);
Assert.assertEquals(str, decryptStr);
}
@Test
public void readECPrivateKeyTest() {
final PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_sec1_private_key.pem"));
final SM2 sm2 = new SM2(privateKey, null);
sm2.usePlainEncoding();
//需要签名的明文,得到明文对应的字节数组
final byte[] dataBytes = "我是一段测试aaaa".getBytes(StandardCharsets.UTF_8);
final byte[] sign = sm2.sign(dataBytes, null);
// 64位签名
Assert.assertEquals(64, sign.length);
}
@Test
@Ignore
public void readECPrivateKeyTest2() {
// https://gitee.com/dromara/hutool/issues/I37Z75
final byte[] d = PemUtil.readPem(FileUtil.getInputStream("d:/test/keys/priv.key"));
final byte[] publicKey = PemUtil.readPem(FileUtil.getInputStream("d:/test/keys/pub.key"));
final SM2 sm2 = new SM2(d, publicKey);
sm2.usePlainEncoding();
final String content = "我是Hanley.";
final byte[] sign = sm2.sign(StrUtil.utf8Bytes(content));
final boolean verify = sm2.verify(StrUtil.utf8Bytes(content), sign);
Assert.assertTrue(verify);
}
}

View File

@@ -1,4 +1,4 @@
package cn.hutool.crypto.test;
package cn.hutool.crypto;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.KeyUtil;

View File

@@ -1,9 +1,6 @@
package cn.hutool.crypto.test.asymmetric;
package cn.hutool.crypto.asymmetric;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.AsymmetricCrypto;
import cn.hutool.crypto.asymmetric.ECIES;
import cn.hutool.crypto.asymmetric.KeyType;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,7 +1,6 @@
package cn.hutool.crypto.test.asymmetric;
package cn.hutool.crypto.asymmetric;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.Console;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.HexUtil;
@@ -9,11 +8,6 @@ import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,4 +1,4 @@
package cn.hutool.crypto.test.asymmetric;
package cn.hutool.crypto.asymmetric;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
@@ -8,8 +8,6 @@ import cn.hutool.crypto.ECKeyUtil;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.SmUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.jcajce.spec.OpenSSHPrivateKeySpec;

View File

@@ -1,10 +1,8 @@
package cn.hutool.crypto.test.asymmetric;
package cn.hutool.crypto.asymmetric;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.Sign;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,6 +1,5 @@
package cn.hutool.crypto.test.digest;
package cn.hutool.crypto.digest;
import cn.hutool.crypto.digest.BCrypt;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,4 +1,4 @@
package cn.hutool.crypto.test.digest;
package cn.hutool.crypto.digest;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.digest.mac.Mac;

View File

@@ -1,12 +1,9 @@
package cn.hutool.crypto.test.digest;
package cn.hutool.crypto.digest;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.crypto.digest.Digester;
/**
* 摘要算法单元测试
@@ -14,40 +11,40 @@ import cn.hutool.crypto.digest.Digester;
*
*/
public class DigestTest {
@Test
public void digesterTest(){
String testStr = "test中文";
Digester md5 = new Digester(DigestAlgorithm.MD5);
String digestHex = md5.digestHex(testStr);
Assert.assertEquals("5393554e94bf0eb6436f240a4fd71282", digestHex);
}
@Test
public void md5Test(){
String testStr = "test中文";
String md5Hex1 = DigestUtil.md5Hex(testStr);
Assert.assertEquals("5393554e94bf0eb6436f240a4fd71282", md5Hex1);
String md5Hex2 = DigestUtil.md5Hex(IoUtil.toStream(testStr, CharsetUtil.CHARSET_UTF_8));
Assert.assertEquals("5393554e94bf0eb6436f240a4fd71282", md5Hex2);
}
@Test
public void md5WithSaltTest(){
String testStr = "test中文";
Digester md5 = new Digester(DigestAlgorithm.MD5);
//加盐
md5.setSalt("saltTest".getBytes());
String md5Hex1 = md5.digestHex(testStr);
Assert.assertEquals("762f7335200299dfa09bebbb601a5bc6", md5Hex1);
String md5Hex2 = md5.digestHex(IoUtil.toUtf8Stream(testStr));
Assert.assertEquals("762f7335200299dfa09bebbb601a5bc6", md5Hex2);
//重复2次
md5.setDigestCount(2);
String md5Hex3 = md5.digestHex(testStr);
@@ -55,18 +52,18 @@ public class DigestTest {
String md5Hex4 = md5.digestHex(IoUtil.toUtf8Stream(testStr));
Assert.assertEquals("2b0616296f6755d25efc07f90afe9684", md5Hex4);
}
@Test
public void sha1Test(){
String testStr = "test中文";
String sha1Hex1 = DigestUtil.sha1Hex(testStr);
Assert.assertEquals("ecabf586cef0d3b11c56549433ad50b81110a836", sha1Hex1);
String sha1Hex2 = DigestUtil.sha1Hex(IoUtil.toStream(testStr, CharsetUtil.CHARSET_UTF_8));
Assert.assertEquals("ecabf586cef0d3b11c56549433ad50b81110a836", sha1Hex2);
}
@Test
public void hash256Test() {
String testStr = "Test中文";

View File

@@ -1,11 +1,9 @@
package cn.hutool.crypto.test.digest;
package cn.hutool.crypto.digest;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.HMac;
import cn.hutool.crypto.digest.HmacAlgorithm;
import cn.hutool.crypto.symmetric.ZUC;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,13 +1,11 @@
package cn.hutool.crypto.test.digest;
package cn.hutool.crypto.digest;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.crypto.digest.MD5;
/**
* MD5 单元测试
*
*
* @author Looly
*
*/

View File

@@ -1,7 +1,6 @@
package cn.hutool.crypto.test.digest;
package cn.hutool.crypto.digest;
import cn.hutool.core.codec.Base32;
import cn.hutool.crypto.digest.HmacAlgorithm;
import cn.hutool.crypto.digest.otp.HOTP;
import cn.hutool.crypto.digest.otp.TOTP;
import org.junit.Assert;

View File

@@ -1,4 +1,4 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.HexUtil;
@@ -6,7 +6,6 @@ import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,8 +1,7 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.symmetric.ChaCha20;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,10 +1,9 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,4 +1,4 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;

View File

@@ -1,13 +1,11 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.core.util.CharsetUtil;
import org.junit.Assert;
import org.junit.Test;
import cn.hutool.crypto.symmetric.RC4;
public class RC4Test {
@Test
public void testCryptMessage() {
String key = "This is pretty long key";
@@ -16,7 +14,7 @@ public class RC4Test {
byte[] crypt = rc4.encrypt(message);
String msg = rc4.decrypt(crypt);
Assert.assertEquals(message, msg);
String message2 = "Hello, World this is megssage 2";
byte[] crypt2 = rc4.encrypt(message2);
String msg2 = rc4.decrypt(crypt2);
@@ -31,7 +29,7 @@ public class RC4Test {
byte[] crypt = rc4.encrypt(message);
String msg = rc4.decrypt(crypt);
Assert.assertEquals(message, msg);
String message2 = "这是第二个中文消息!";
byte[] crypt2 = rc4.encrypt(message2);
String msg2 = rc4.decrypt(crypt2);

View File

@@ -1,6 +1,5 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.crypto.symmetric.SM4;
import org.junit.Ignore;
import org.junit.Test;

View File

@@ -1,4 +1,4 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
@@ -9,12 +9,6 @@ import cn.hutool.crypto.KeyUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import cn.hutool.crypto.symmetric.DES;
import cn.hutool.crypto.symmetric.DESede;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.hutool.crypto.symmetric.Vigenere;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,7 +1,5 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import cn.hutool.crypto.symmetric.XXTEA;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,8 +1,7 @@
package cn.hutool.crypto.test.symmetric;
package cn.hutool.crypto.symmetric;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.symmetric.ZUC;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,7 +1,6 @@
package cn.hutool.crypto.test.symmetric.fpe;
package cn.hutool.crypto.symmetric.fpe;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.symmetric.fpe.FPE;
import org.bouncycastle.crypto.util.BasicAlphabetMapper;
import org.junit.Assert;
import org.junit.Test;

View File

@@ -1,123 +0,0 @@
package cn.hutool.crypto.test;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.PemUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.crypto.asymmetric.SM2;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.*;
public class PemUtilTest {
@Test
public void readPrivateKeyTest() {
PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_private_key.pem"));
Assert.assertNotNull(privateKey);
}
@Test
public void readPublicKeyTest() {
PublicKey publicKey = PemUtil.readPemPublicKey(ResourceUtil.getStream("test_public_key.csr"));
Assert.assertNotNull(publicKey);
}
@Test
public void readPemKeyTest() {
PublicKey publicKey = (PublicKey) PemUtil.readPemKey(ResourceUtil.getStream("test_public_key.csr"));
Assert.assertNotNull(publicKey);
}
@Test
public void validateKey() {
PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_private_key.pem"));
PublicKey publicKey = PemUtil.readPemPublicKey(ResourceUtil.getStream("test_public_key.csr"));
RSA rsa = new RSA(privateKey, publicKey);
String str = "你好Hutool";//测试字符串
String encryptStr = rsa.encryptBase64(str, KeyType.PublicKey);
String decryptStr = rsa.decryptStr(encryptStr, KeyType.PrivateKey);
Assert.assertEquals(str, decryptStr);
}
@Test
public void readECPrivateKeyTest() {
PrivateKey privateKey = PemUtil.readSm2PemPrivateKey(ResourceUtil.getStream("test_ec_sec1_private_key.pem"));
SM2 sm2 = new SM2(privateKey, null);
sm2.usePlainEncoding();
//需要签名的明文,得到明文对应的字节数组
byte[] dataBytes = "我是一段测试aaaa".getBytes(StandardCharsets.UTF_8);
byte[] sign = sm2.sign(dataBytes, null);
// 64位签名
Assert.assertEquals(64, sign.length);
}
@Test
@Ignore
public void readECPrivateKeyTest2() {
// https://gitee.com/dromara/hutool/issues/I37Z75
byte[] d = PemUtil.readPem(FileUtil.getInputStream("d:/test/keys/priv.key"));
byte[] publicKey = PemUtil.readPem(FileUtil.getInputStream("d:/test/keys/pub.key"));
SM2 sm2 = new SM2(d, publicKey);
sm2.usePlainEncoding();
String content = "我是Hanley.";
byte[] sign = sm2.sign(StrUtil.utf8Bytes(content));
boolean verify = sm2.verify(StrUtil.utf8Bytes(content), sign);
Assert.assertTrue(verify);
}
@Test
public void verifyPemUtilReadKey() {
// 公钥
// PKCS#10 文件读取公钥
PublicKey csrPublicKey = PemUtil.readPemPublicKey(ResourceUtil.getStream("test_ec_certificate_request.csr"));
// 证书读取公钥
PublicKey certPublicKey = PemUtil.readPemPublicKey(ResourceUtil.getStream("test_ec_certificate.cer"));
// PEM 公钥
PublicKey plainPublicKey = PemUtil.readPemPublicKey(ResourceUtil.getStream("test_ec_public_key.pem"));
// 私钥
// 加密的 PEM 私钥
PrivateKey encPrivateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_encrypted_private_key.key"), "123456".toCharArray());
// PKCS#8 私钥
PrivateKey pkcs8PrivateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_pkcs8_private_key.key"));
// SEC 1 私钥
PrivateKey sec1PrivateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_sec1_private_key.pem"));
// 组装还原后的公钥和私钥列表
List<PublicKey> publicKeyList = Arrays.asList(csrPublicKey, certPublicKey, plainPublicKey);
List<PrivateKey> privateKeyList = Arrays.asList(encPrivateKey, pkcs8PrivateKey, sec1PrivateKey);
// 做笛卡尔积循环验证
for (PrivateKey privateKeyItem : privateKeyList) {
for (PublicKey publicKeyItem : publicKeyList) {
// 校验公私钥
SM2 genSm2 = new SM2(privateKeyItem, publicKeyItem);
genSm2.usePlainEncoding();
String content = "我是Hanley.";
byte[] sign = genSm2.sign(StrUtil.utf8Bytes(content));
boolean verify = genSm2.verify(StrUtil.utf8Bytes(content), sign);
Assert.assertTrue(verify);
}
}
}
}