mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
add method
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
* 【crypto 】 Sm2增加getD和getQ方法(issue#I37Z4C@Gitee)
|
||||
* 【cache 】 AbstractCache增加keySet方法(issue#I37Z4C@Gitee)
|
||||
* 【core 】 NumberWordFormatter增加formatSimple方法(pr#1436@Github)
|
||||
* 【crypto 】 增加读取openSSL生成的sm2私钥
|
||||
|
||||
### Bug修复
|
||||
* 【json 】 JSONUtil.isJson方法改变trim策略,解决特殊空白符导致判断失败问题
|
||||
|
@@ -1,5 +1,11 @@
|
||||
package cn.hutool.crypto;
|
||||
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import org.bouncycastle.asn1.ASN1Encoding;
|
||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||
import org.bouncycastle.asn1.sec.ECPrivateKey;
|
||||
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
||||
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
|
||||
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
@@ -8,6 +14,7 @@ import org.bouncycastle.jcajce.provider.asymmetric.util.ECUtil;
|
||||
import org.bouncycastle.math.ec.ECCurve;
|
||||
import org.bouncycastle.util.BigIntegers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
@@ -262,4 +269,19 @@ public class ECKeyUtil {
|
||||
throw new CryptoException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将SM2算法的{@link ECPrivateKey} 转换为 {@link PrivateKey}
|
||||
* @param privateKey {@link ECPrivateKey}
|
||||
* @return {@link PrivateKey}
|
||||
*/
|
||||
public static PrivateKey toSm2PrivateKey(ECPrivateKey privateKey){
|
||||
try {
|
||||
final PrivateKeyInfo info = new PrivateKeyInfo(
|
||||
new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, SmUtil.ID_SM2_PUBLIC_KEY_PARAM), privateKey);
|
||||
return KeyUtil.generatePrivateKey("SM2", info.getEncoded(ASN1Encoding.DER));
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,6 +3,7 @@ package cn.hutool.crypto;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.bouncycastle.asn1.sec.ECPrivateKey;
|
||||
import org.bouncycastle.util.io.pem.PemObject;
|
||||
import org.bouncycastle.util.io.pem.PemObjectGenerator;
|
||||
import org.bouncycastle.util.io.pem.PemReader;
|
||||
@@ -159,4 +160,15 @@ public class PemUtil {
|
||||
IoUtil.close(writer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取OpenSSL生成的ANS1格式的Pem私钥文件
|
||||
*
|
||||
* @param keyStream 私钥pem流
|
||||
* @return {@link PrivateKey}
|
||||
*/
|
||||
public static PrivateKey readSm2PemPrivateKey(InputStream keyStream){
|
||||
final ECPrivateKey ecPrivateKey = ECPrivateKey.getInstance(readPem(keyStream));
|
||||
return ECKeyUtil.toSm2PrivateKey(ecPrivateKey);
|
||||
}
|
||||
}
|
||||
|
@@ -10,6 +10,7 @@ import cn.hutool.crypto.digest.mac.BCHMacEngine;
|
||||
import cn.hutool.crypto.digest.mac.MacEngine;
|
||||
import cn.hutool.crypto.symmetric.SM4;
|
||||
import cn.hutool.crypto.symmetric.SymmetricCrypto;
|
||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.bouncycastle.asn1.gm.GMNamedCurves;
|
||||
import org.bouncycastle.crypto.digests.SM3Digest;
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
@@ -31,6 +32,7 @@ import java.math.BigInteger;
|
||||
*/
|
||||
public class SmUtil {
|
||||
|
||||
private final static int RS_LEN = 32;
|
||||
/**
|
||||
* SM2默认曲线
|
||||
*/
|
||||
@@ -38,13 +40,11 @@ public class SmUtil {
|
||||
/**
|
||||
* SM2推荐曲线参数(来自https://github.com/ZZMarquis/gmhelper)
|
||||
*/
|
||||
public static final ECDomainParameters SM2_DOMAIN_PARAMS;
|
||||
|
||||
private final static int RS_LEN = 32;
|
||||
|
||||
static {
|
||||
SM2_DOMAIN_PARAMS = BCUtil.toDomainParams(GMNamedCurves.getByName(SM2_CURVE_NAME));
|
||||
}
|
||||
public static final ECDomainParameters SM2_DOMAIN_PARAMS = BCUtil.toDomainParams(GMNamedCurves.getByName(SM2_CURVE_NAME));
|
||||
/**
|
||||
* SM2国密算法公钥参数的Oid标识
|
||||
*/
|
||||
public static final ASN1ObjectIdentifier ID_SM2_PUBLIC_KEY_PARAM = new ASN1ObjectIdentifier("1.2.156.10197.1.301");
|
||||
|
||||
/**
|
||||
* 创建SM2算法对象<br>
|
||||
|
@@ -4,10 +4,11 @@ import cn.hutool.core.io.resource.ResourceUtil;
|
||||
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;
|
||||
|
||||
@@ -45,9 +46,16 @@ public class PemUtilTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void readECPrivateKeyTest() {
|
||||
PrivateKey privateKey = PemUtil.readPemPrivateKey(ResourceUtil.getStream("test_ec_private_key.pem"));
|
||||
Assert.assertNotNull(privateKey);
|
||||
PrivateKey privateKey = PemUtil.readSm2PemPrivateKey(ResourceUtil.getStream("test_ec_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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user