mirror of
https://gitee.com/BDWare/gmhelper
synced 2025-01-10 09:54:09 +00:00
build: config spotless plugin and reformat code
This commit is contained in:
parent
4d620b64f3
commit
b9ac471185
@ -4,6 +4,9 @@ plugins {
|
|||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
id 'signing'
|
id 'signing'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply from: '../spotless.gradle'
|
||||||
|
|
||||||
group 'org.bdware.bdcontract'
|
group 'org.bdware.bdcontract'
|
||||||
version '0.2.0'
|
version '0.2.0'
|
||||||
sourceCompatibility = 1.8
|
sourceCompatibility = 1.8
|
||||||
|
@ -57,15 +57,12 @@ public class BCECUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static KeyPair generateKeyPair(ECDomainParameters domainParameters, SecureRandom random)
|
public static KeyPair generateKeyPair(ECDomainParameters domainParameters, SecureRandom random)
|
||||||
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
throws NoSuchProviderException, NoSuchAlgorithmException,
|
||||||
|
InvalidAlgorithmParameterException {
|
||||||
KeyPairGenerator kpg =
|
KeyPairGenerator kpg =
|
||||||
KeyPairGenerator.getInstance(ALGO_NAME_EC, BouncyCastleProvider.PROVIDER_NAME);
|
KeyPairGenerator.getInstance(ALGO_NAME_EC, BouncyCastleProvider.PROVIDER_NAME);
|
||||||
ECParameterSpec parameterSpec =
|
ECParameterSpec parameterSpec = new ECParameterSpec(domainParameters.getCurve(),
|
||||||
new ECParameterSpec(
|
domainParameters.getG(), domainParameters.getN(), domainParameters.getH());
|
||||||
domainParameters.getCurve(),
|
|
||||||
domainParameters.getG(),
|
|
||||||
domainParameters.getN(),
|
|
||||||
domainParameters.getH());
|
|
||||||
kpg.initialize(parameterSpec, (null == random ? new SecureRandom() : random));
|
kpg.initialize(parameterSpec, (null == random ? new SecureRandom() : random));
|
||||||
return kpg.generateKeyPair();
|
return kpg.generateKeyPair();
|
||||||
}
|
}
|
||||||
@ -97,8 +94,8 @@ public class BCECUtil {
|
|||||||
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ECPrivateKeyParameters createECPrivateKeyParameters(
|
public static ECPrivateKeyParameters createECPrivateKeyParameters(String dHex,
|
||||||
String dHex, ECDomainParameters domainParameters) {
|
ECDomainParameters domainParameters) {
|
||||||
return createECPrivateKeyParameters(ByteUtils.fromHexString(dHex), domainParameters);
|
return createECPrivateKeyParameters(ByteUtils.fromHexString(dHex), domainParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,8 +104,8 @@ public class BCECUtil {
|
|||||||
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ECPrivateKeyParameters createECPrivateKeyParameters(
|
public static ECPrivateKeyParameters createECPrivateKeyParameters(byte[] dBytes,
|
||||||
byte[] dBytes, ECDomainParameters domainParameters) {
|
ECDomainParameters domainParameters) {
|
||||||
return createECPrivateKeyParameters(new BigInteger(1, dBytes), domainParameters);
|
return createECPrivateKeyParameters(new BigInteger(1, dBytes), domainParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,8 +114,8 @@ public class BCECUtil {
|
|||||||
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ECPrivateKeyParameters createECPrivateKeyParameters(
|
public static ECPrivateKeyParameters createECPrivateKeyParameters(BigInteger d,
|
||||||
BigInteger d, ECDomainParameters domainParameters) {
|
ECDomainParameters domainParameters) {
|
||||||
return new ECPrivateKeyParameters(d, domainParameters);
|
return new ECPrivateKeyParameters(d, domainParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +125,8 @@ public class BCECUtil {
|
|||||||
* @param priKey ECC私钥参数对象
|
* @param priKey ECC私钥参数对象
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ECPublicKeyParameters buildECPublicKeyByPrivateKey(ECPrivateKeyParameters priKey) {
|
public static ECPublicKeyParameters buildECPublicKeyByPrivateKey(
|
||||||
|
ECPrivateKeyParameters priKey) {
|
||||||
ECDomainParameters domainParameters = priKey.getParameters();
|
ECDomainParameters domainParameters = priKey.getParameters();
|
||||||
ECPoint q = new FixedPointCombMultiplier().multiply(domainParameters.getG(), priKey.getD());
|
ECPoint q = new FixedPointCombMultiplier().multiply(domainParameters.getG(), priKey.getD());
|
||||||
return new ECPublicKeyParameters(q, domainParameters);
|
return new ECPublicKeyParameters(q, domainParameters);
|
||||||
@ -141,9 +139,10 @@ public class BCECUtil {
|
|||||||
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ECPublicKeyParameters createECPublicKeyParameters(
|
public static ECPublicKeyParameters createECPublicKeyParameters(BigInteger x, BigInteger y,
|
||||||
BigInteger x, BigInteger y, ECCurve curve, ECDomainParameters domainParameters) {
|
ECCurve curve, ECDomainParameters domainParameters) {
|
||||||
return createECPublicKeyParameters(x.toByteArray(), y.toByteArray(), curve, domainParameters);
|
return createECPublicKeyParameters(x.toByteArray(), y.toByteArray(), curve,
|
||||||
|
domainParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,10 +152,10 @@ public class BCECUtil {
|
|||||||
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ECPublicKeyParameters createECPublicKeyParameters(
|
public static ECPublicKeyParameters createECPublicKeyParameters(String xHex, String yHex,
|
||||||
String xHex, String yHex, ECCurve curve, ECDomainParameters domainParameters) {
|
ECCurve curve, ECDomainParameters domainParameters) {
|
||||||
return createECPublicKeyParameters(
|
return createECPublicKeyParameters(ByteUtils.fromHexString(xHex),
|
||||||
ByteUtils.fromHexString(xHex), ByteUtils.fromHexString(yHex), curve, domainParameters);
|
ByteUtils.fromHexString(yHex), curve, domainParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -166,8 +165,8 @@ public class BCECUtil {
|
|||||||
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
* @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS}
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ECPublicKeyParameters createECPublicKeyParameters(
|
public static ECPublicKeyParameters createECPublicKeyParameters(byte[] xBytes, byte[] yBytes,
|
||||||
byte[] xBytes, byte[] yBytes, ECCurve curve, ECDomainParameters domainParameters) {
|
ECCurve curve, ECDomainParameters domainParameters) {
|
||||||
final byte uncompressedFlag = 0x04;
|
final byte uncompressedFlag = 0x04;
|
||||||
int curveLength = getCurveLength(domainParameters);
|
int curveLength = getCurveLength(domainParameters);
|
||||||
xBytes = fixToCurveLengthBytes(curveLength, xBytes);
|
xBytes = fixToCurveLengthBytes(curveLength, xBytes);
|
||||||
@ -186,38 +185,29 @@ public class BCECUtil {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static ECPublicKeyParameters createECPublicKeyFromStrParameters(
|
public static ECPublicKeyParameters createECPublicKeyFromStrParameters(String str,
|
||||||
String str, ECCurve curve, ECDomainParameters domainParameters) {
|
ECCurve curve, ECDomainParameters domainParameters) {
|
||||||
return new ECPublicKeyParameters(
|
return new ECPublicKeyParameters(curve.decodePoint(ByteUtils.fromHexString(str)),
|
||||||
curve.decodePoint(ByteUtils.fromHexString(str)), domainParameters);
|
domainParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ECPrivateKeyParameters convertPrivateKeyToParameters(BCECPrivateKey ecPriKey) {
|
public static ECPrivateKeyParameters convertPrivateKeyToParameters(BCECPrivateKey ecPriKey) {
|
||||||
ECParameterSpec parameterSpec = ecPriKey.getParameters();
|
ECParameterSpec parameterSpec = ecPriKey.getParameters();
|
||||||
ECDomainParameters domainParameters =
|
ECDomainParameters domainParameters = new ECDomainParameters(parameterSpec.getCurve(),
|
||||||
new ECDomainParameters(
|
parameterSpec.getG(), parameterSpec.getN(), parameterSpec.getH());
|
||||||
parameterSpec.getCurve(),
|
|
||||||
parameterSpec.getG(),
|
|
||||||
parameterSpec.getN(),
|
|
||||||
parameterSpec.getH());
|
|
||||||
return new ECPrivateKeyParameters(ecPriKey.getD(), domainParameters);
|
return new ECPrivateKeyParameters(ecPriKey.getD(), domainParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ECPublicKeyParameters convertPublicKeyToParameters(BCECPublicKey ecPubKey) {
|
public static ECPublicKeyParameters convertPublicKeyToParameters(BCECPublicKey ecPubKey) {
|
||||||
ECParameterSpec parameterSpec = ecPubKey.getParameters();
|
ECParameterSpec parameterSpec = ecPubKey.getParameters();
|
||||||
ECDomainParameters domainParameters =
|
ECDomainParameters domainParameters = new ECDomainParameters(parameterSpec.getCurve(),
|
||||||
new ECDomainParameters(
|
parameterSpec.getG(), parameterSpec.getN(), parameterSpec.getH());
|
||||||
parameterSpec.getCurve(),
|
|
||||||
parameterSpec.getG(),
|
|
||||||
parameterSpec.getN(),
|
|
||||||
parameterSpec.getH());
|
|
||||||
return new ECPublicKeyParameters(ecPubKey.getQ(), domainParameters);
|
return new ECPublicKeyParameters(ecPubKey.getQ(), domainParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BCECPublicKey createPublicKeyFromSubjectPublicKeyInfo(
|
public static BCECPublicKey createPublicKeyFromSubjectPublicKeyInfo(
|
||||||
SubjectPublicKeyInfo subPubInfo)
|
SubjectPublicKeyInfo subPubInfo) throws NoSuchProviderException,
|
||||||
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException,
|
NoSuchAlgorithmException, InvalidKeySpecException, IOException {
|
||||||
IOException {
|
|
||||||
return BCECUtil.convertX509ToECPublicKey(
|
return BCECUtil.convertX509ToECPublicKey(
|
||||||
subPubInfo.toASN1Primitive().getEncoded(ASN1Encoding.DER));
|
subPubInfo.toASN1Primitive().getEncoded(ASN1Encoding.DER));
|
||||||
}
|
}
|
||||||
@ -229,19 +219,18 @@ public class BCECUtil {
|
|||||||
* @param pubKey 可以为空,但是如果为空的话得到的结果OpenSSL可能解析不了
|
* @param pubKey 可以为空,但是如果为空的话得到的结果OpenSSL可能解析不了
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static byte[] convertECPrivateKeyToPKCS8(
|
public static byte[] convertECPrivateKeyToPKCS8(ECPrivateKeyParameters priKey,
|
||||||
ECPrivateKeyParameters priKey, ECPublicKeyParameters pubKey) {
|
ECPublicKeyParameters pubKey) {
|
||||||
ECDomainParameters domainParams = priKey.getParameters();
|
ECDomainParameters domainParams = priKey.getParameters();
|
||||||
ECParameterSpec spec =
|
ECParameterSpec spec = new ECParameterSpec(domainParams.getCurve(), domainParams.getG(),
|
||||||
new ECParameterSpec(
|
domainParams.getN(), domainParams.getH());
|
||||||
domainParams.getCurve(), domainParams.getG(), domainParams.getN(), domainParams.getH());
|
|
||||||
BCECPublicKey publicKey = null;
|
BCECPublicKey publicKey = null;
|
||||||
if (pubKey != null) {
|
if (pubKey != null) {
|
||||||
publicKey = new BCECPublicKey(ALGO_NAME_EC, pubKey, spec, BouncyCastleProvider.CONFIGURATION);
|
publicKey = new BCECPublicKey(ALGO_NAME_EC, pubKey, spec,
|
||||||
|
BouncyCastleProvider.CONFIGURATION);
|
||||||
}
|
}
|
||||||
BCECPrivateKey privateKey =
|
BCECPrivateKey privateKey = new BCECPrivateKey(ALGO_NAME_EC, priKey, publicKey, spec,
|
||||||
new BCECPrivateKey(
|
BouncyCastleProvider.CONFIGURATION);
|
||||||
ALGO_NAME_EC, priKey, publicKey, spec, BouncyCastleProvider.CONFIGURATION);
|
|
||||||
return privateKey.getEncoded();
|
return privateKey.getEncoded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,8 +281,8 @@ public class BCECUtil {
|
|||||||
* @return
|
* @return
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static byte[] convertECPrivateKeyToSEC1(
|
public static byte[] convertECPrivateKeyToSEC1(ECPrivateKeyParameters priKey,
|
||||||
ECPrivateKeyParameters priKey, ECPublicKeyParameters pubKey) throws IOException {
|
ECPublicKeyParameters pubKey) throws IOException {
|
||||||
byte[] pkcs8Bytes = convertECPrivateKeyToPKCS8(priKey, pubKey);
|
byte[] pkcs8Bytes = convertECPrivateKeyToPKCS8(priKey, pubKey);
|
||||||
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(pkcs8Bytes);
|
PrivateKeyInfo pki = PrivateKeyInfo.getInstance(pkcs8Bytes);
|
||||||
ASN1Encodable encodable = pki.parsePrivateKey();
|
ASN1Encodable encodable = pki.parsePrivateKey();
|
||||||
@ -368,9 +357,8 @@ public class BCECUtil {
|
|||||||
*/
|
*/
|
||||||
public static byte[] convertECPublicKeyToX509(ECPublicKeyParameters pubKey) {
|
public static byte[] convertECPublicKeyToX509(ECPublicKeyParameters pubKey) {
|
||||||
ECDomainParameters domainParams = pubKey.getParameters();
|
ECDomainParameters domainParams = pubKey.getParameters();
|
||||||
ECParameterSpec spec =
|
ECParameterSpec spec = new ECParameterSpec(domainParams.getCurve(), domainParams.getG(),
|
||||||
new ECParameterSpec(
|
domainParams.getN(), domainParams.getH());
|
||||||
domainParams.getCurve(), domainParams.getG(), domainParams.getN(), domainParams.getH());
|
|
||||||
BCECPublicKey publicKey =
|
BCECPublicKey publicKey =
|
||||||
new BCECPublicKey(ALGO_NAME_EC, pubKey, spec, BouncyCastleProvider.CONFIGURATION);
|
new BCECPublicKey(ALGO_NAME_EC, pubKey, spec, BouncyCastleProvider.CONFIGURATION);
|
||||||
return publicKey.getEncoded();
|
return publicKey.getEncoded();
|
||||||
@ -473,22 +461,17 @@ public class BCECUtil {
|
|||||||
} else {
|
} else {
|
||||||
ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
|
ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve());
|
||||||
|
|
||||||
X9ECParameters ecP =
|
X9ECParameters ecP = new X9ECParameters(curve,
|
||||||
new X9ECParameters(
|
new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()),
|
||||||
curve,
|
withCompression),
|
||||||
new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression),
|
ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()),
|
||||||
ecSpec.getOrder(),
|
|
||||||
BigInteger.valueOf(ecSpec.getCofactor()),
|
|
||||||
ecSpec.getCurve().getSeed());
|
ecSpec.getCurve().getSeed());
|
||||||
|
|
||||||
//// 如果是1.62或更低版本的bcprov-jdk15on应该使用以下这段代码,因为高版本的EC5Util.convertPoint没有向下兼容
|
//// 如果是1.62或更低版本的bcprov-jdk15on应该使用以下这段代码,因为高版本的EC5Util.convertPoint没有向下兼容
|
||||||
/*
|
/*
|
||||||
X9ECParameters ecP = new X9ECParameters(
|
* X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve,
|
||||||
curve,
|
* ecSpec.getGenerator(), withCompression), ecSpec.getOrder(),
|
||||||
EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression),
|
* BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed());
|
||||||
ecSpec.getOrder(),
|
|
||||||
BigInteger.valueOf(ecSpec.getCofactor()),
|
|
||||||
ecSpec.getCurve().getSeed());
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params = new X962Parameters(ecP);
|
params = new X962Parameters(ecP);
|
||||||
|
@ -18,15 +18,15 @@ public class SM2KeyExchangeUtil {
|
|||||||
* @return 返回协商出的密钥,但是这个密钥是没有经过确认的
|
* @return 返回协商出的密钥,但是这个密钥是没有经过确认的
|
||||||
*/
|
*/
|
||||||
public static byte[] calculateKey(boolean initiator, int keyBits,
|
public static byte[] calculateKey(boolean initiator, int keyBits,
|
||||||
ECPrivateKeyParameters selfStaticPriv, ECPrivateKeyParameters selfEphemeralPriv, byte[] selfId,
|
ECPrivateKeyParameters selfStaticPriv, ECPrivateKeyParameters selfEphemeralPriv,
|
||||||
ECPublicKeyParameters otherStaticPub, ECPublicKeyParameters otherEphemeralPub, byte[] otherId) {
|
byte[] selfId, ECPublicKeyParameters otherStaticPub,
|
||||||
|
ECPublicKeyParameters otherEphemeralPub, byte[] otherId) {
|
||||||
SM2KeyExchange exch = new SM2KeyExchange();
|
SM2KeyExchange exch = new SM2KeyExchange();
|
||||||
exch.init(new ParametersWithID(
|
exch.init(new ParametersWithID(
|
||||||
new SM2KeyExchangePrivateParameters(initiator, selfStaticPriv, selfEphemeralPriv),
|
new SM2KeyExchangePrivateParameters(initiator, selfStaticPriv, selfEphemeralPriv),
|
||||||
selfId));
|
selfId));
|
||||||
return exch.calculateKey(
|
return exch.calculateKey(keyBits, new ParametersWithID(
|
||||||
keyBits,
|
new SM2KeyExchangePublicParameters(otherStaticPub, otherEphemeralPub), otherId));
|
||||||
new ParametersWithID(new SM2KeyExchangePublicParameters(otherStaticPub, otherEphemeralPub), otherId));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,17 +41,19 @@ public class SM2KeyExchangeUtil {
|
|||||||
* @param otherId 对方ID
|
* @param otherId 对方ID
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static ExchangeResult calculateKeyWithConfirmation(boolean initiator, int keyBits, byte[] confirmationTag,
|
public static ExchangeResult calculateKeyWithConfirmation(boolean initiator, int keyBits,
|
||||||
ECPrivateKeyParameters selfStaticPriv, ECPrivateKeyParameters selfEphemeralPriv, byte[] selfId,
|
byte[] confirmationTag, ECPrivateKeyParameters selfStaticPriv,
|
||||||
ECPublicKeyParameters otherStaticPub, ECPublicKeyParameters otherEphemeralPub, byte[] otherId) {
|
ECPrivateKeyParameters selfEphemeralPriv, byte[] selfId,
|
||||||
|
ECPublicKeyParameters otherStaticPub, ECPublicKeyParameters otherEphemeralPub,
|
||||||
|
byte[] otherId) {
|
||||||
SM2KeyExchange exch = new SM2KeyExchange();
|
SM2KeyExchange exch = new SM2KeyExchange();
|
||||||
exch.init(new ParametersWithID(
|
exch.init(new ParametersWithID(
|
||||||
new SM2KeyExchangePrivateParameters(initiator, selfStaticPriv, selfEphemeralPriv),
|
new SM2KeyExchangePrivateParameters(initiator, selfStaticPriv, selfEphemeralPriv),
|
||||||
selfId));
|
selfId));
|
||||||
byte[][] result = exch.calculateKeyWithConfirmation(
|
byte[][] result = exch.calculateKeyWithConfirmation(keyBits, confirmationTag,
|
||||||
keyBits,
|
new ParametersWithID(
|
||||||
confirmationTag,
|
new SM2KeyExchangePublicParameters(otherStaticPub, otherEphemeralPub),
|
||||||
new ParametersWithID(new SM2KeyExchangePublicParameters(otherStaticPub, otherEphemeralPub), otherId));
|
otherId));
|
||||||
ExchangeResult confirmResult = new ExchangeResult();
|
ExchangeResult confirmResult = new ExchangeResult();
|
||||||
confirmResult.setKey(result[0]);
|
confirmResult.setKey(result[0]);
|
||||||
if (initiator) {
|
if (initiator) {
|
||||||
|
@ -32,15 +32,14 @@ public class SM2KeyPair {
|
|||||||
JsonObject jo = JsonParser.parseString(jsonStr).getAsJsonObject();
|
JsonObject jo = JsonParser.parseString(jsonStr).getAsJsonObject();
|
||||||
String publicKeyStr = jo.get("publicKey").getAsString();
|
String publicKeyStr = jo.get("publicKey").getAsString();
|
||||||
String privateKeyStr = jo.get("privateKey").getAsString();
|
String privateKeyStr = jo.get("privateKey").getAsString();
|
||||||
ECPublicKeyParameters point =
|
ECPublicKeyParameters point = BCECUtil.createECPublicKeyFromStrParameters(publicKeyStr,
|
||||||
BCECUtil.createECPublicKeyFromStrParameters(
|
SM2Util.CURVE, SM2Util.DOMAIN_PARAMS);
|
||||||
publicKeyStr, SM2Util.CURVE, SM2Util.DOMAIN_PARAMS);
|
|
||||||
return new SM2KeyPair(point, new BigInteger(privateKeyStr, 16));
|
return new SM2KeyPair(point, new BigInteger(privateKeyStr, 16));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ECPublicKeyParameters publicKeyStr2ECPoint(String pubKey) {
|
public static ECPublicKeyParameters publicKeyStr2ECPoint(String pubKey) {
|
||||||
return BCECUtil.createECPublicKeyFromStrParameters(
|
return BCECUtil.createECPublicKeyFromStrParameters(pubKey, SM2Util.CURVE,
|
||||||
pubKey, SM2Util.CURVE, SM2Util.DOMAIN_PARAMS);
|
SM2Util.DOMAIN_PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ECPublicKeyParameters getPublicKey() {
|
public ECPublicKeyParameters getPublicKey() {
|
||||||
@ -74,28 +73,15 @@ public class SM2KeyPair {
|
|||||||
|
|
||||||
public KeyPair toJavaSecurity() {
|
public KeyPair toJavaSecurity() {
|
||||||
ECDomainParameters domainParams = privateKey.getParameters();
|
ECDomainParameters domainParams = privateKey.getParameters();
|
||||||
ECParameterSpec spec =
|
ECParameterSpec spec = new ECParameterSpec(domainParams.getCurve(), domainParams.getG(),
|
||||||
new ECParameterSpec(
|
domainParams.getN(), domainParams.getH());
|
||||||
domainParams.getCurve(),
|
|
||||||
domainParams.getG(),
|
|
||||||
domainParams.getN(),
|
|
||||||
domainParams.getH());
|
|
||||||
BCECPublicKey bcPublicKey = null;
|
BCECPublicKey bcPublicKey = null;
|
||||||
BCECPrivateKey bcPrivateKey;
|
BCECPrivateKey bcPrivateKey;
|
||||||
if (null != publicKey) {
|
if (null != publicKey) {
|
||||||
bcPublicKey =
|
bcPublicKey = new BCECPublicKey(BCECUtil.ALGO_NAME_EC, publicKey, spec,
|
||||||
new BCECPublicKey(
|
|
||||||
BCECUtil.ALGO_NAME_EC,
|
|
||||||
publicKey,
|
|
||||||
spec,
|
|
||||||
BouncyCastleProvider.CONFIGURATION);
|
BouncyCastleProvider.CONFIGURATION);
|
||||||
}
|
}
|
||||||
bcPrivateKey =
|
bcPrivateKey = new BCECPrivateKey(BCECUtil.ALGO_NAME_EC, privateKey, bcPublicKey, spec,
|
||||||
new BCECPrivateKey(
|
|
||||||
BCECUtil.ALGO_NAME_EC,
|
|
||||||
privateKey,
|
|
||||||
bcPublicKey,
|
|
||||||
spec,
|
|
||||||
BouncyCastleProvider.CONFIGURATION);
|
BouncyCastleProvider.CONFIGURATION);
|
||||||
return new KeyPair(bcPublicKey, bcPrivateKey);
|
return new KeyPair(bcPublicKey, bcPrivateKey);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,8 @@ public class SM2PreprocessSigner implements ECConstants {
|
|||||||
* @param param
|
* @param param
|
||||||
* @throws RuntimeException
|
* @throws RuntimeException
|
||||||
*/
|
*/
|
||||||
public void init(boolean forSigning, Digest digest, CipherParameters param) throws RuntimeException {
|
public void init(boolean forSigning, Digest digest, CipherParameters param)
|
||||||
|
throws RuntimeException {
|
||||||
CipherParameters baseParam;
|
CipherParameters baseParam;
|
||||||
|
|
||||||
if (digest.getDigestSize() != DIGEST_LENGTH) {
|
if (digest.getDigestSize() != DIGEST_LENGTH) {
|
||||||
@ -76,7 +77,8 @@ public class SM2PreprocessSigner implements ECConstants {
|
|||||||
ecParams = ecKey.getParameters();
|
ecParams = ecKey.getParameters();
|
||||||
kCalculator.init(ecParams.getN(), CryptoServicesRegistrar.getSecureRandom());
|
kCalculator.init(ecParams.getN(), CryptoServicesRegistrar.getSecureRandom());
|
||||||
}
|
}
|
||||||
pubPoint = createBasePointMultiplier().multiply(ecParams.getG(), ((ECPrivateKeyParameters) ecKey).getD()).normalize();
|
pubPoint = createBasePointMultiplier()
|
||||||
|
.multiply(ecParams.getG(), ((ECPrivateKeyParameters) ecKey).getD()).normalize();
|
||||||
} else {
|
} else {
|
||||||
ecKey = (ECKeyParameters) baseParam;
|
ecKey = (ECKeyParameters) baseParam;
|
||||||
ecParams = ecKey.getParameters();
|
ecParams = ecKey.getParameters();
|
||||||
@ -85,10 +87,7 @@ public class SM2PreprocessSigner implements ECConstants {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预处理,辅助方法
|
* 预处理,辅助方法 ZA=H256(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥yG ∥ xA ∥ yA)。 M=ZA ∥ M; e = Hv(M)
|
||||||
* ZA=H256(ENT LA ∥ IDA ∥ a ∥ b ∥ xG ∥yG ∥ xA ∥ yA)。
|
|
||||||
* M=ZA ∥ M;
|
|
||||||
* e = Hv(M)
|
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@ -140,16 +139,14 @@ public class SM2PreprocessSigner implements ECConstants {
|
|||||||
|
|
||||||
// A5
|
// A5
|
||||||
r = e.add(p.getAffineXCoord().toBigInteger()).mod(n);
|
r = e.add(p.getAffineXCoord().toBigInteger()).mod(n);
|
||||||
}
|
} while (r.equals(ZERO) || r.add(k).equals(n));
|
||||||
while (r.equals(ZERO) || r.add(k).equals(n));
|
|
||||||
|
|
||||||
// A6
|
// A6
|
||||||
BigInteger dPlus1ModN = d.add(ONE).modInverse(n);
|
BigInteger dPlus1ModN = d.add(ONE).modInverse(n);
|
||||||
|
|
||||||
s = k.subtract(r.multiply(d)).mod(n);
|
s = k.subtract(r.multiply(d)).mod(n);
|
||||||
s = dPlus1ModN.multiply(s).mod(n);
|
s = dPlus1ModN.multiply(s).mod(n);
|
||||||
}
|
} while (s.equals(ZERO));
|
||||||
while (s.equals(ZERO));
|
|
||||||
|
|
||||||
// A7
|
// A7
|
||||||
try {
|
try {
|
||||||
@ -245,8 +242,7 @@ public class SM2PreprocessSigner implements ECConstants {
|
|||||||
return new BigInteger(1, message);
|
return new BigInteger(1, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BigInteger[] derDecode(byte[] encoding)
|
protected BigInteger[] derDecode(byte[] encoding) throws IOException {
|
||||||
throws IOException {
|
|
||||||
ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(encoding));
|
ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(encoding));
|
||||||
if (seq.size() != 2) {
|
if (seq.size() != 2) {
|
||||||
return null;
|
return null;
|
||||||
@ -260,11 +256,10 @@ public class SM2PreprocessSigner implements ECConstants {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BigInteger[]{r, s};
|
return new BigInteger[] {r, s};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected byte[] derEncode(BigInteger r, BigInteger s)
|
protected byte[] derEncode(BigInteger r, BigInteger s) throws IOException {
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
ASN1EncodableVector v = new ASN1EncodableVector();
|
ASN1EncodableVector v = new ASN1EncodableVector();
|
||||||
v.add(new ASN1Integer(r));
|
v.add(new ASN1Integer(r));
|
||||||
|
@ -70,11 +70,11 @@ public class SM2Signer implements Signer, ECConstants {
|
|||||||
} else {
|
} else {
|
||||||
this.ecKey = (ECKeyParameters) var3;
|
this.ecKey = (ECKeyParameters) var3;
|
||||||
this.ecParams = this.ecKey.getParameters();
|
this.ecParams = this.ecKey.getParameters();
|
||||||
this.kCalculator.init(this.ecParams.getN(), CryptoServicesRegistrar.getSecureRandom());
|
this.kCalculator.init(this.ecParams.getN(),
|
||||||
|
CryptoServicesRegistrar.getSecureRandom());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.pubPoint =
|
this.pubPoint = this.createBasePointMultiplier()
|
||||||
this.createBasePointMultiplier()
|
|
||||||
.multiply(this.ecParams.getG(), ((ECPrivateKeyParameters) this.ecKey).getD())
|
.multiply(this.ecParams.getG(), ((ECPrivateKeyParameters) this.ecKey).getD())
|
||||||
.normalize();
|
.normalize();
|
||||||
} else {
|
} else {
|
||||||
@ -114,7 +114,7 @@ public class SM2Signer implements Signer, ECConstants {
|
|||||||
public byte[] generateSignature() throws CryptoException {
|
public byte[] generateSignature() throws CryptoException {
|
||||||
byte[] var1 = this.digestDoFinal();
|
byte[] var1 = this.digestDoFinal();
|
||||||
BigInteger n = this.ecParams.getN();
|
BigInteger n = this.ecParams.getN();
|
||||||
BigInteger var3 = this.calculateE(n , var1);
|
BigInteger var3 = this.calculateE(n, var1);
|
||||||
BigInteger var4 = ((ECPrivateKeyParameters) this.ecKey).getD();
|
BigInteger var4 = ((ECPrivateKeyParameters) this.ecKey).getD();
|
||||||
ECMultiplier var7 = this.createBasePointMultiplier();
|
ECMultiplier var7 = this.createBasePointMultiplier();
|
||||||
|
|
||||||
@ -127,7 +127,7 @@ public class SM2Signer implements Signer, ECConstants {
|
|||||||
var5 = var3.add(var9.getAffineXCoord().toBigInteger()).mod(n);
|
var5 = var3.add(var9.getAffineXCoord().toBigInteger()).mod(n);
|
||||||
} while (var5.equals(ZERO));
|
} while (var5.equals(ZERO));
|
||||||
|
|
||||||
if (!var5.add(k).equals(n )) {
|
if (!var5.add(k).equals(n)) {
|
||||||
BigInteger var11 = BigIntegers.modOddInverse(n, var4.add(ONE));
|
BigInteger var11 = BigIntegers.modOddInverse(n, var4.add(ONE));
|
||||||
BigInteger var6 = k.subtract(var5.multiply(var4)).mod(n);
|
BigInteger var6 = k.subtract(var5.multiply(var4)).mod(n);
|
||||||
var6 = var11.multiply(var6).mod(n);
|
var6 = var11.multiply(var6).mod(n);
|
||||||
@ -135,7 +135,8 @@ public class SM2Signer implements Signer, ECConstants {
|
|||||||
try {
|
try {
|
||||||
return this.encoding.encode(this.ecParams.getN(), var5, var6);
|
return this.encoding.encode(this.ecParams.getN(), var5, var6);
|
||||||
} catch (Exception var10) {
|
} catch (Exception var10) {
|
||||||
throw new CryptoException("unable to encode signature: " + var10.getMessage(), var10);
|
throw new CryptoException(
|
||||||
|
"unable to encode signature: " + var10.getMessage(), var10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,8 +154,8 @@ public class SM2Signer implements Signer, ECConstants {
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
ECPoint var7 = ((ECPublicKeyParameters) this.ecKey).getQ();
|
ECPoint var7 = ((ECPublicKeyParameters) this.ecKey).getQ();
|
||||||
ECPoint var8 =
|
ECPoint var8 = ECAlgorithms
|
||||||
ECAlgorithms.sumOfTwoMultiplies(this.ecParams.getG(), var2, var7, var6).normalize();
|
.sumOfTwoMultiplies(this.ecParams.getG(), var2, var7, var6).normalize();
|
||||||
if (var8.isInfinity()) {
|
if (var8.isInfinity()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
|
@ -44,19 +44,15 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
public static final EllipticCurve JDK_CURVE =
|
public static final EllipticCurve JDK_CURVE =
|
||||||
new EllipticCurve(new ECFieldFp(SM2_ECC_P), SM2_ECC_A, SM2_ECC_B);
|
new EllipticCurve(new ECFieldFp(SM2_ECC_P), SM2_ECC_A, SM2_ECC_B);
|
||||||
public static final java.security.spec.ECPoint JDK_G_POINT =
|
public static final java.security.spec.ECPoint JDK_G_POINT = new java.security.spec.ECPoint(
|
||||||
new java.security.spec.ECPoint(
|
G_POINT.getAffineXCoord().toBigInteger(), G_POINT.getAffineYCoord().toBigInteger());
|
||||||
G_POINT.getAffineXCoord().toBigInteger(),
|
|
||||||
G_POINT.getAffineYCoord().toBigInteger());
|
|
||||||
public static final java.security.spec.ECParameterSpec JDK_EC_SPEC =
|
public static final java.security.spec.ECParameterSpec JDK_EC_SPEC =
|
||||||
new java.security.spec.ECParameterSpec(
|
new java.security.spec.ECParameterSpec(JDK_CURVE, JDK_G_POINT, SM2_ECC_N,
|
||||||
JDK_CURVE, JDK_G_POINT, SM2_ECC_N, SM2_ECC_H.intValue());
|
SM2_ECC_H.intValue());
|
||||||
public static final int SM3_DIGEST_LENGTH = 32;
|
public static final int SM3_DIGEST_LENGTH = 32;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
static ECCurve.Fp SM2_ECC_FP =
|
static ECCurve.Fp SM2_ECC_FP = new ECCurve.Fp(SM2_ECC_P, // q
|
||||||
new ECCurve.Fp(
|
|
||||||
SM2_ECC_P, // q
|
|
||||||
SM2_ECC_A, // a
|
SM2_ECC_A, // a
|
||||||
SM2_ECC_B); // b
|
SM2_ECC_B); // b
|
||||||
|
|
||||||
@ -79,9 +75,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException
|
||||||
* @throws InvalidAlgorithmParameterException
|
* @throws InvalidAlgorithmParameterException
|
||||||
*/
|
*/
|
||||||
public static KeyPair generateKeyPair(SecureRandom random)
|
public static KeyPair generateKeyPair(SecureRandom random) throws NoSuchProviderException,
|
||||||
throws NoSuchProviderException, NoSuchAlgorithmException,
|
NoSuchAlgorithmException, InvalidAlgorithmParameterException {
|
||||||
InvalidAlgorithmParameterException {
|
|
||||||
return BCECUtil.generateKeyPair(DOMAIN_PARAMS, random);
|
return BCECUtil.generateKeyPair(DOMAIN_PARAMS, random);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,8 +90,7 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
BCECPrivateKey privateKey = (BCECPrivateKey) key.getPrivate();
|
BCECPrivateKey privateKey = (BCECPrivateKey) key.getPrivate();
|
||||||
BCECPublicKey publicKey = (BCECPublicKey) key.getPublic();
|
BCECPublicKey publicKey = (BCECPublicKey) key.getPublic();
|
||||||
byte[] point = publicKey.getQ().getEncoded(false);
|
byte[] point = publicKey.getQ().getEncoded(false);
|
||||||
ECPublicKeyParameters parameters =
|
ECPublicKeyParameters parameters = BCECUtil.createECPublicKeyFromStrParameters(
|
||||||
BCECUtil.createECPublicKeyFromStrParameters(
|
|
||||||
ByteUtils.toHexString(point), CURVE, DOMAIN_PARAMS);
|
ByteUtils.toHexString(point), CURVE, DOMAIN_PARAMS);
|
||||||
return new SM2KeyPair(parameters, privateKey.getD());
|
return new SM2KeyPair(parameters, privateKey.getD());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -181,7 +175,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param priKey 私钥
|
* @param priKey 私钥
|
||||||
* @param sm2Cipher 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param sm2Cipher
|
||||||
|
* 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。
|
* @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。
|
||||||
* @throws InvalidCipherTextException
|
* @throws InvalidCipherTextException
|
||||||
*/
|
*/
|
||||||
@ -194,7 +189,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
/**
|
/**
|
||||||
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
||||||
* @param priKey 私钥
|
* @param priKey 私钥
|
||||||
* @param sm2Cipher 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param sm2Cipher
|
||||||
|
* 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。
|
* @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。
|
||||||
* @throws InvalidCipherTextException
|
* @throws InvalidCipherTextException
|
||||||
*/
|
*/
|
||||||
@ -206,7 +202,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param priKeyParameters 私钥
|
* @param priKeyParameters 私钥
|
||||||
* @param sm2Cipher 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param sm2Cipher
|
||||||
|
* 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。
|
* @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。
|
||||||
* @throws InvalidCipherTextException
|
* @throws InvalidCipherTextException
|
||||||
*/
|
*/
|
||||||
@ -218,13 +215,13 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
/**
|
/**
|
||||||
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
||||||
* @param priKeyParameters 私钥
|
* @param priKeyParameters 私钥
|
||||||
* @param sm2Cipher 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param sm2Cipher
|
||||||
|
* 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。
|
* @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。
|
||||||
* @throws InvalidCipherTextException
|
* @throws InvalidCipherTextException
|
||||||
*/
|
*/
|
||||||
public static byte[] decrypt(
|
public static byte[] decrypt(Mode mode, ECPrivateKeyParameters priKeyParameters,
|
||||||
Mode mode, ECPrivateKeyParameters priKeyParameters, byte[] sm2Cipher)
|
byte[] sm2Cipher) throws InvalidCipherTextException {
|
||||||
throws InvalidCipherTextException {
|
|
||||||
SM2Engine engine = new SM2Engine(mode);
|
SM2Engine engine = new SM2Engine(mode);
|
||||||
engine.init(false, priKeyParameters);
|
engine.init(false, priKeyParameters);
|
||||||
if (sm2Cipher[0] != 4) {
|
if (sm2Cipher[0] != 4) {
|
||||||
@ -239,7 +236,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
/**
|
/**
|
||||||
* 分解SM2密文
|
* 分解SM2密文
|
||||||
*
|
*
|
||||||
* @param cipherText 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param cipherText
|
||||||
|
* 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@ -252,7 +250,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
* 分解SM2密文
|
* 分解SM2密文
|
||||||
*
|
*
|
||||||
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
||||||
* @param cipherText 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param cipherText
|
||||||
|
* 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static SM2Cipher parseSM2Cipher(Mode mode, byte[] cipherText) throws Exception {
|
public static SM2Cipher parseSM2Cipher(Mode mode, byte[] cipherText) throws Exception {
|
||||||
@ -263,7 +262,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
/**
|
/**
|
||||||
* @param curveLength 曲线长度,SM2的话就是256位。
|
* @param curveLength 曲线长度,SM2的话就是256位。
|
||||||
* @param digestLength 摘要长度,如果是SM2的话因为默认使用SM3摘要,SM3摘要长度为32字节。
|
* @param digestLength 摘要长度,如果是SM2的话因为默认使用SM3摘要,SM3摘要长度为32字节。
|
||||||
* @param cipherText 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param cipherText
|
||||||
|
* 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@ -278,11 +278,12 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
||||||
* @param curveLength 曲线长度,SM2的话就是256位。
|
* @param curveLength 曲线长度,SM2的话就是256位。
|
||||||
* @param digestLength 摘要长度,如果是SM2的话因为默认使用SM3摘要,SM3摘要长度为32字节。
|
* @param digestLength 摘要长度,如果是SM2的话因为默认使用SM3摘要,SM3摘要长度为32字节。
|
||||||
* @param cipherText 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param cipherText
|
||||||
|
* 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static SM2Cipher parseSM2Cipher(
|
public static SM2Cipher parseSM2Cipher(Mode mode, int curveLength, int digestLength,
|
||||||
Mode mode, int curveLength, int digestLength, byte[] cipherText) throws Exception {
|
byte[] cipherText) throws Exception {
|
||||||
byte[] c1 = new byte[curveLength * 2 + 1];
|
byte[] c1 = new byte[curveLength * 2 + 1];
|
||||||
byte[] c2 = new byte[cipherText.length - c1.length - digestLength];
|
byte[] c2 = new byte[cipherText.length - c1.length - digestLength];
|
||||||
byte[] c3 = new byte[digestLength];
|
byte[] c3 = new byte[digestLength];
|
||||||
@ -322,7 +323,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
* DER编码密文
|
* DER编码密文
|
||||||
*
|
*
|
||||||
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
||||||
* @param cipher 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param cipher
|
||||||
|
* 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return 按指定mode DER编码后的密文
|
* @return 按指定mode DER编码后的密文
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
@ -349,12 +351,13 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
* @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2
|
||||||
* @param curveLength 曲线长度,SM2的话就是256位。
|
* @param curveLength 曲线长度,SM2的话就是256位。
|
||||||
* @param digestLength 摘要长度,如果是SM2的话因为默认使用SM3摘要,SM3摘要长度为32字节。
|
* @param digestLength 摘要长度,如果是SM2的话因为默认使用SM3摘要,SM3摘要长度为32字节。
|
||||||
* @param cipher 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
* @param cipher
|
||||||
|
* 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。
|
||||||
* @return 按指定mode DER编码后的密文
|
* @return 按指定mode DER编码后的密文
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static byte[] encodeSM2CipherToDER(
|
public static byte[] encodeSM2CipherToDER(Mode mode, int curveLength, int digestLength,
|
||||||
Mode mode, int curveLength, int digestLength, byte[] cipher) throws Exception {
|
byte[] cipher) throws Exception {
|
||||||
|
|
||||||
byte[] c1x = new byte[curveLength];
|
byte[] c1x = new byte[curveLength];
|
||||||
byte[] c1y = new byte[curveLength];
|
byte[] c1y = new byte[curveLength];
|
||||||
@ -379,8 +382,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ASN1Encodable[] arr = new ASN1Encodable[4];
|
ASN1Encodable[] arr = new ASN1Encodable[4];
|
||||||
arr[0] = new ASN1Integer(new BigInteger(1,c1x));
|
arr[0] = new ASN1Integer(new BigInteger(1, c1x));
|
||||||
arr[1] = new ASN1Integer(new BigInteger(1,c1y));
|
arr[1] = new ASN1Integer(new BigInteger(1, c1y));
|
||||||
if (mode == Mode.C1C2C3) {
|
if (mode == Mode.C1C2C3) {
|
||||||
arr[2] = new DEROctetString(c2);
|
arr[2] = new DEROctetString(c2);
|
||||||
arr[3] = new DEROctetString(c3);
|
arr[3] = new DEROctetString(c3);
|
||||||
@ -497,9 +500,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
* @return DER编码后的签名值
|
* @return DER编码后的签名值
|
||||||
* @throws CryptoException
|
* @throws CryptoException
|
||||||
*/
|
*/
|
||||||
public static byte[] sign(
|
public static byte[] sign(ECPrivateKeyParameters priKeyParameters, byte[] withId,
|
||||||
ECPrivateKeyParameters priKeyParameters, byte[] withId, byte[] srcData)
|
byte[] srcData) throws CryptoException {
|
||||||
throws CryptoException {
|
|
||||||
SM2Signer signer = new SM2Signer();
|
SM2Signer signer = new SM2Signer();
|
||||||
CipherParameters param = null;
|
CipherParameters param = null;
|
||||||
ParametersWithRandom pwr = new ParametersWithRandom(priKeyParameters, new SecureRandom());
|
ParametersWithRandom pwr = new ParametersWithRandom(priKeyParameters, new SecureRandom());
|
||||||
@ -580,8 +582,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
* @param sign DER编码的签名值
|
* @param sign DER编码的签名值
|
||||||
* @return 验签成功返回true,失败返回false
|
* @return 验签成功返回true,失败返回false
|
||||||
*/
|
*/
|
||||||
public static boolean verify(
|
public static boolean verify(ECPublicKeyParameters pubKeyParameters, byte[] srcData,
|
||||||
ECPublicKeyParameters pubKeyParameters, byte[] srcData, byte[] sign) {
|
byte[] sign) {
|
||||||
return verify(pubKeyParameters, null, srcData, sign);
|
return verify(pubKeyParameters, null, srcData, sign);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -608,8 +610,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
* @param sign DER编码的签名值
|
* @param sign DER编码的签名值
|
||||||
* @return 验签成功返回true,失败返回false
|
* @return 验签成功返回true,失败返回false
|
||||||
*/
|
*/
|
||||||
public static boolean verify(
|
public static boolean verify(ECPublicKeyParameters pubKeyParameters, byte[] withId,
|
||||||
ECPublicKeyParameters pubKeyParameters, byte[] withId, byte[] srcData, byte[] sign) {
|
byte[] srcData, byte[] sign) {
|
||||||
SM2Signer signer = new SM2Signer();
|
SM2Signer signer = new SM2Signer();
|
||||||
CipherParameters param;
|
CipherParameters param;
|
||||||
if (withId != null) {
|
if (withId != null) {
|
||||||
@ -651,9 +653,8 @@ public class SM2Util extends GMBaseUtil {
|
|||||||
// } catch (Exception e) {
|
// } catch (Exception e) {
|
||||||
// e.printStackTrace();
|
// e.printStackTrace();
|
||||||
// }
|
// }
|
||||||
ECPublicKeyParameters pubkey =
|
ECPublicKeyParameters pubkey = BCECUtil.createECPublicKeyFromStrParameters(publicKey,
|
||||||
BCECUtil.createECPublicKeyFromStrParameters(
|
SM2Util.CURVE, SM2Util.DOMAIN_PARAMS);
|
||||||
publicKey, SM2Util.CURVE, SM2Util.DOMAIN_PARAMS);
|
|
||||||
boolean result = SM2Util.verify(pubkey, toVerify.getBytes(), sigByte);
|
boolean result = SM2Util.verify(pubkey, toVerify.getBytes(), sigByte);
|
||||||
return result;
|
return result;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -32,8 +32,10 @@ public class SM4Util extends GMBaseUtil {
|
|||||||
return generateKey(DEFAULT_KEY_SIZE);
|
return generateKey(DEFAULT_KEY_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] generateKey(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException {
|
public static byte[] generateKey(int keySize)
|
||||||
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
|
throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||||
|
KeyGenerator kg =
|
||||||
|
KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
|
||||||
kg.init(keySize, new SecureRandom());
|
kg.init(keySize, new SecureRandom());
|
||||||
return kg.generateKey().getEncoded();
|
return kg.generateKey().getEncoded();
|
||||||
}
|
}
|
||||||
@ -86,7 +88,8 @@ public class SM4Util extends GMBaseUtil {
|
|||||||
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException,
|
||||||
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
|
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException,
|
||||||
InvalidAlgorithmParameterException {
|
InvalidAlgorithmParameterException {
|
||||||
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.ENCRYPT_MODE, key, iv);
|
Cipher cipher =
|
||||||
|
generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.ENCRYPT_MODE, key, iv);
|
||||||
return cipher.doFinal(data);
|
return cipher.doFinal(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,18 +97,20 @@ public class SM4Util extends GMBaseUtil {
|
|||||||
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException,
|
||||||
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
|
||||||
InvalidAlgorithmParameterException {
|
InvalidAlgorithmParameterException {
|
||||||
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.DECRYPT_MODE, key, iv);
|
Cipher cipher =
|
||||||
|
generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.DECRYPT_MODE, key, iv);
|
||||||
return cipher.doFinal(cipherText);
|
return cipher.doFinal(cipherText);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] doCMac(byte[] key, byte[] data) throws NoSuchProviderException, NoSuchAlgorithmException,
|
public static byte[] doCMac(byte[] key, byte[] data)
|
||||||
InvalidKeyException {
|
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
|
||||||
Key keyObj = new SecretKeySpec(key, ALGORITHM_NAME);
|
Key keyObj = new SecretKeySpec(key, ALGORITHM_NAME);
|
||||||
return doMac("SM4-CMAC", keyObj, data);
|
return doMac("SM4-CMAC", keyObj, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] doGMac(byte[] key, byte[] iv, int tagLength, byte[] data) {
|
public static byte[] doGMac(byte[] key, byte[] iv, int tagLength, byte[] data) {
|
||||||
org.bouncycastle.crypto.Mac mac = new GMac(new GCMBlockCipher(new SM4Engine()), tagLength * 8);
|
org.bouncycastle.crypto.Mac mac =
|
||||||
|
new GMac(new GCMBlockCipher(new SM4Engine()), tagLength * 8);
|
||||||
return doMac(mac, key, iv, data);
|
return doMac(mac, key, iv, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +124,8 @@ public class SM4Util extends GMBaseUtil {
|
|||||||
*/
|
*/
|
||||||
public static byte[] doCBCMac(byte[] key, byte[] iv, byte[] data) {
|
public static byte[] doCBCMac(byte[] key, byte[] iv, byte[] data) {
|
||||||
SM4Engine engine = new SM4Engine();
|
SM4Engine engine = new SM4Engine();
|
||||||
org.bouncycastle.crypto.Mac mac = new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, new PKCS7Padding());
|
org.bouncycastle.crypto.Mac mac =
|
||||||
|
new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, new PKCS7Padding());
|
||||||
return doMac(mac, key, iv, data);
|
return doMac(mac, key, iv, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,19 +137,22 @@ public class SM4Util extends GMBaseUtil {
|
|||||||
* @return
|
* @return
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static byte[] doCBCMac(byte[] key, byte[] iv, BlockCipherPadding padding, byte[] data) throws Exception {
|
public static byte[] doCBCMac(byte[] key, byte[] iv, BlockCipherPadding padding, byte[] data)
|
||||||
|
throws Exception {
|
||||||
SM4Engine engine = new SM4Engine();
|
SM4Engine engine = new SM4Engine();
|
||||||
if (padding == null) {
|
if (padding == null) {
|
||||||
if (data.length % engine.getBlockSize() != 0) {
|
if (data.length % engine.getBlockSize() != 0) {
|
||||||
throw new Exception("if no padding, data length must be multiple of SM4 BlockSize");
|
throw new Exception("if no padding, data length must be multiple of SM4 BlockSize");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
org.bouncycastle.crypto.Mac mac = new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, padding);
|
org.bouncycastle.crypto.Mac mac =
|
||||||
|
new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, padding);
|
||||||
return doMac(mac, key, iv, data);
|
return doMac(mac, key, iv, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static byte[] doMac(org.bouncycastle.crypto.Mac mac, byte[] key, byte[] iv, byte[] data) {
|
private static byte[] doMac(org.bouncycastle.crypto.Mac mac, byte[] key, byte[] iv,
|
||||||
|
byte[] data) {
|
||||||
CipherParameters cipherParameters = new KeyParameter(key);
|
CipherParameters cipherParameters = new KeyParameter(key);
|
||||||
mac.init(new ParametersWithIV(cipherParameters, iv));
|
mac.init(new ParametersWithIV(cipherParameters, iv));
|
||||||
mac.update(data, 0, data.length);
|
mac.update(data, 0, data.length);
|
||||||
@ -152,8 +161,8 @@ public class SM4Util extends GMBaseUtil {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] doMac(String algorithmName, Key key, byte[] data) throws NoSuchProviderException,
|
private static byte[] doMac(String algorithmName, Key key, byte[] data)
|
||||||
NoSuchAlgorithmException, InvalidKeyException {
|
throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException {
|
||||||
Mac mac = Mac.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
|
Mac mac = Mac.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
|
||||||
mac.init(key);
|
mac.init(key);
|
||||||
mac.update(data);
|
mac.update(data);
|
||||||
@ -170,8 +179,8 @@ public class SM4Util extends GMBaseUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv)
|
private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv)
|
||||||
throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException,
|
throws InvalidKeyException, InvalidAlgorithmParameterException,
|
||||||
NoSuchProviderException, NoSuchPaddingException {
|
NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException {
|
||||||
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
|
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
|
||||||
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
|
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
|
||||||
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
|
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
|
||||||
|
@ -29,7 +29,8 @@ public class CommonUtil {
|
|||||||
* @return
|
* @return
|
||||||
* @throws InvalidX500NameException
|
* @throws InvalidX500NameException
|
||||||
*/
|
*/
|
||||||
public static X500Name buildX500Name(Map<String, String> names) throws InvalidX500NameException {
|
public static X500Name buildX500Name(Map<String, String> names)
|
||||||
|
throws InvalidX500NameException {
|
||||||
if (names == null || names.size() == 0) {
|
if (names == null || names.size() == 0) {
|
||||||
throw new InvalidX500NameException("names can not be empty");
|
throw new InvalidX500NameException("names can not be empty");
|
||||||
}
|
}
|
||||||
@ -49,21 +50,24 @@ public class CommonUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PKCS10CertificationRequest createCSR(X500Name subject, SM2PublicKey pubKey, PrivateKey priKey,
|
public static PKCS10CertificationRequest createCSR(X500Name subject, SM2PublicKey pubKey,
|
||||||
String signAlgo) throws OperatorCreationException {
|
PrivateKey priKey, String signAlgo) throws OperatorCreationException {
|
||||||
PKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(subject, pubKey);
|
PKCS10CertificationRequestBuilder csrBuilder =
|
||||||
|
new JcaPKCS10CertificationRequestBuilder(subject, pubKey);
|
||||||
ContentSigner signerBuilder = new JcaContentSignerBuilder(signAlgo)
|
ContentSigner signerBuilder = new JcaContentSignerBuilder(signAlgo)
|
||||||
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(priKey);
|
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(priKey);
|
||||||
return csrBuilder.build(signerBuilder);
|
return csrBuilder.build(signerBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlgorithmIdentifier findSignatureAlgorithmIdentifier(String algoName) {
|
public static AlgorithmIdentifier findSignatureAlgorithmIdentifier(String algoName) {
|
||||||
DefaultSignatureAlgorithmIdentifierFinder sigFinder = new DefaultSignatureAlgorithmIdentifierFinder();
|
DefaultSignatureAlgorithmIdentifierFinder sigFinder =
|
||||||
|
new DefaultSignatureAlgorithmIdentifierFinder();
|
||||||
return sigFinder.find(algoName);
|
return sigFinder.find(algoName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AlgorithmIdentifier findDigestAlgorithmIdentifier(String algoName) {
|
public static AlgorithmIdentifier findDigestAlgorithmIdentifier(String algoName) {
|
||||||
DefaultDigestAlgorithmIdentifierFinder digFinder = new DefaultDigestAlgorithmIdentifierFinder();
|
DefaultDigestAlgorithmIdentifierFinder digFinder =
|
||||||
|
new DefaultDigestAlgorithmIdentifierFinder();
|
||||||
return digFinder.find(findSignatureAlgorithmIdentifier(algoName));
|
return digFinder.find(findSignatureAlgorithmIdentifier(algoName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -47,14 +47,15 @@ public class RandomSNAllocator implements CertSNAllocator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor with the specification of bitLen.
|
* Constructor with the specification of bitLen.
|
||||||
|
*
|
||||||
* @param bitLen bit length of the serial number. The highest bit is always set to 1, so the
|
* @param bitLen bit length of the serial number. The highest bit is always set to 1, so the
|
||||||
* effective bit length is bitLen - 1. Valid value is [65, 159].
|
* effective bit length is bitLen - 1. Valid value is [65, 159].
|
||||||
*/
|
*/
|
||||||
public RandomSNAllocator(int bitLen) {
|
public RandomSNAllocator(int bitLen) {
|
||||||
if (bitLen < MIN_SERIALNUMBER_SIZE || bitLen > MAX_SERIALNUMBER_SIZE) {
|
if (bitLen < MIN_SERIALNUMBER_SIZE || bitLen > MAX_SERIALNUMBER_SIZE) {
|
||||||
throw new IllegalArgumentException(String.format(
|
throw new IllegalArgumentException(
|
||||||
"%s may not be out of the range [%d, %d]: %d",
|
String.format("%s may not be out of the range [%d, %d]: %d", "bitLen",
|
||||||
"bitLen", MIN_SERIALNUMBER_SIZE, MAX_SERIALNUMBER_SIZE, bitLen));
|
MIN_SERIALNUMBER_SIZE, MAX_SERIALNUMBER_SIZE, bitLen));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.random = new SecureRandom();
|
this.random = new SecureRandom();
|
||||||
|
@ -55,8 +55,8 @@ public class SM2CertUtil {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate getX509Certificate(String certFilePath) throws IOException, CertificateException,
|
public static X509Certificate getX509Certificate(String certFilePath)
|
||||||
NoSuchProviderException {
|
throws IOException, CertificateException, NoSuchProviderException {
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
try {
|
try {
|
||||||
is = new FileInputStream(certFilePath);
|
is = new FileInputStream(certFilePath);
|
||||||
@ -68,20 +68,21 @@ public class SM2CertUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate getX509Certificate(byte[] certBytes) throws CertificateException,
|
public static X509Certificate getX509Certificate(byte[] certBytes)
|
||||||
NoSuchProviderException {
|
throws CertificateException, NoSuchProviderException {
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(certBytes);
|
ByteArrayInputStream bais = new ByteArrayInputStream(certBytes);
|
||||||
return getX509Certificate(bais);
|
return getX509Certificate(bais);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate getX509Certificate(InputStream is) throws CertificateException,
|
public static X509Certificate getX509Certificate(InputStream is)
|
||||||
NoSuchProviderException {
|
throws CertificateException, NoSuchProviderException {
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
|
CertificateFactory cf =
|
||||||
|
CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
|
||||||
return (X509Certificate) cf.generateCertificate(is);
|
return (X509Certificate) cf.generateCertificate(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CertPath getCertificateChain(String certChainPath) throws IOException, CertificateException,
|
public static CertPath getCertificateChain(String certChainPath)
|
||||||
NoSuchProviderException {
|
throws IOException, CertificateException, NoSuchProviderException {
|
||||||
InputStream is = null;
|
InputStream is = null;
|
||||||
try {
|
try {
|
||||||
is = new FileInputStream(certChainPath);
|
is = new FileInputStream(certChainPath);
|
||||||
@ -93,30 +94,37 @@ public class SM2CertUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CertPath getCertificateChain(byte[] certChainBytes) throws CertificateException,
|
public static CertPath getCertificateChain(byte[] certChainBytes)
|
||||||
NoSuchProviderException {
|
throws CertificateException, NoSuchProviderException {
|
||||||
ByteArrayInputStream bais = new ByteArrayInputStream(certChainBytes);
|
ByteArrayInputStream bais = new ByteArrayInputStream(certChainBytes);
|
||||||
return getCertificateChain(bais);
|
return getCertificateChain(bais);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] getCertificateChainBytes(CertPath certChain) throws CertificateEncodingException {
|
public static byte[] getCertificateChainBytes(CertPath certChain)
|
||||||
|
throws CertificateEncodingException {
|
||||||
return certChain.getEncoded("PKCS7");
|
return certChain.getEncoded("PKCS7");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CertPath getCertificateChain(InputStream is) throws CertificateException, NoSuchProviderException {
|
public static CertPath getCertificateChain(InputStream is)
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
|
throws CertificateException, NoSuchProviderException {
|
||||||
|
CertificateFactory cf =
|
||||||
|
CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
|
||||||
return cf.generateCertPath(is, "PKCS7");
|
return cf.generateCertPath(is, "PKCS7");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CertPath getCertificateChain(List<X509Certificate> certs) throws CertificateException,
|
public static CertPath getCertificateChain(List<X509Certificate> certs)
|
||||||
NoSuchProviderException {
|
throws CertificateException, NoSuchProviderException {
|
||||||
CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
|
CertificateFactory cf =
|
||||||
|
CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME);
|
||||||
return cf.generateCertPath(certs);
|
return cf.generateCertPath(certs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static X509Certificate getX509CertificateFromPfx(byte[] pfxDER, String passwd) throws Exception {
|
public static X509Certificate getX509CertificateFromPfx(byte[] pfxDER, String passwd)
|
||||||
InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder()
|
throws Exception {
|
||||||
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(passwd.toCharArray());
|
InputDecryptorProvider inputDecryptorProvider =
|
||||||
|
new JcePKCSPBEInputDecryptorProviderBuilder()
|
||||||
|
.setProvider(BouncyCastleProvider.PROVIDER_NAME)
|
||||||
|
.build(passwd.toCharArray());
|
||||||
PKCS12PfxPdu pfx = new PKCS12PfxPdu(pfxDER);
|
PKCS12PfxPdu pfx = new PKCS12PfxPdu(pfxDER);
|
||||||
|
|
||||||
ContentInfo[] infos = pfx.getContentInfos();
|
ContentInfo[] infos = pfx.getContentInfos();
|
||||||
@ -126,7 +134,8 @@ public class SM2CertUtil {
|
|||||||
|
|
||||||
for (int i = 0; i != infos.length; i++) {
|
for (int i = 0; i != infos.length; i++) {
|
||||||
if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) {
|
if (infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) {
|
||||||
PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider);
|
PKCS12SafeBagFactory dataFact =
|
||||||
|
new PKCS12SafeBagFactory(infos[i], inputDecryptorProvider);
|
||||||
PKCS12SafeBag[] bags = dataFact.getSafeBags();
|
PKCS12SafeBag[] bags = dataFact.getSafeBags();
|
||||||
X509CertificateHolder certHoler = (X509CertificateHolder) bags[0].getBagValue();
|
X509CertificateHolder certHoler = (X509CertificateHolder) bags[0].getBagValue();
|
||||||
return SM2CertUtil.getX509Certificate(certHoler.getEncoded());
|
return SM2CertUtil.getX509Certificate(certHoler.getEncoded());
|
||||||
@ -140,9 +149,12 @@ public class SM2CertUtil {
|
|||||||
return SM2CertUtil.getBCECPublicKey(getX509CertificateFromPfx(pfxDER, passwd));
|
return SM2CertUtil.getBCECPublicKey(getX509CertificateFromPfx(pfxDER, passwd));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BCECPrivateKey getPrivateKeyFromPfx(byte[] pfxDER, String passwd) throws Exception {
|
public static BCECPrivateKey getPrivateKeyFromPfx(byte[] pfxDER, String passwd)
|
||||||
InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder()
|
throws Exception {
|
||||||
.setProvider(BouncyCastleProvider.PROVIDER_NAME).build(passwd.toCharArray());
|
InputDecryptorProvider inputDecryptorProvider =
|
||||||
|
new JcePKCSPBEInputDecryptorProviderBuilder()
|
||||||
|
.setProvider(BouncyCastleProvider.PROVIDER_NAME)
|
||||||
|
.build(passwd.toCharArray());
|
||||||
PKCS12PfxPdu pfx = new PKCS12PfxPdu(pfxDER);
|
PKCS12PfxPdu pfx = new PKCS12PfxPdu(pfxDER);
|
||||||
|
|
||||||
ContentInfo[] infos = pfx.getContentInfos();
|
ContentInfo[] infos = pfx.getContentInfos();
|
||||||
@ -154,7 +166,8 @@ public class SM2CertUtil {
|
|||||||
if (!infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) {
|
if (!infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) {
|
||||||
PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]);
|
PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]);
|
||||||
PKCS12SafeBag[] bags = dataFact.getSafeBags();
|
PKCS12SafeBag[] bags = dataFact.getSafeBags();
|
||||||
PKCS8EncryptedPrivateKeyInfo encInfo = (PKCS8EncryptedPrivateKeyInfo) bags[0].getBagValue();
|
PKCS8EncryptedPrivateKeyInfo encInfo =
|
||||||
|
(PKCS8EncryptedPrivateKeyInfo) bags[0].getBagValue();
|
||||||
PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider);
|
PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider);
|
||||||
BCECPrivateKey privateKey = BCECUtil.convertPKCS8ToECPrivateKey(info.getEncoded());
|
BCECPrivateKey privateKey = BCECUtil.convertPKCS8ToECPrivateKey(info.getEncoded());
|
||||||
return privateKey;
|
return privateKey;
|
||||||
|
@ -29,8 +29,8 @@ public class SM2PfxMaker {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws PKCSException
|
* @throws PKCSException
|
||||||
*/
|
*/
|
||||||
public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate[] chain, String passwd)
|
public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate[] chain,
|
||||||
throws NoSuchAlgorithmException, IOException, PKCSException {
|
String passwd) throws NoSuchAlgorithmException, IOException, PKCSException {
|
||||||
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
|
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
|
||||||
|
|
||||||
PKCS12SafeBagBuilder taCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[2]);
|
PKCS12SafeBagBuilder taCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[2]);
|
||||||
@ -64,8 +64,7 @@ public class SM2PfxMaker {
|
|||||||
certs[2] = taCertBagBuilder.build();
|
certs[2] = taCertBagBuilder.build();
|
||||||
pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder(
|
pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder(
|
||||||
PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC,
|
PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC,
|
||||||
new CBCBlockCipher(new RC2Engine())).build(passwdChars),
|
new CBCBlockCipher(new RC2Engine())).build(passwdChars), certs);
|
||||||
certs);
|
|
||||||
pfxPduBuilder.addData(keyBagBuilder.build());
|
pfxPduBuilder.addData(keyBagBuilder.build());
|
||||||
return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwdChars);
|
return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwdChars);
|
||||||
}
|
}
|
||||||
@ -80,8 +79,8 @@ public class SM2PfxMaker {
|
|||||||
* @throws IOException
|
* @throws IOException
|
||||||
* @throws PKCSException
|
* @throws PKCSException
|
||||||
*/
|
*/
|
||||||
public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate cert, String passwd)
|
public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate cert,
|
||||||
throws NoSuchAlgorithmException, IOException, PKCSException {
|
String passwd) throws NoSuchAlgorithmException, IOException, PKCSException {
|
||||||
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
|
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
|
||||||
|
|
||||||
PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(cert);
|
PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(cert);
|
||||||
@ -105,8 +104,7 @@ public class SM2PfxMaker {
|
|||||||
certs[0] = eeCertBagBuilder.build();
|
certs[0] = eeCertBagBuilder.build();
|
||||||
pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder(
|
pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder(
|
||||||
PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC,
|
PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC,
|
||||||
new CBCBlockCipher(new RC2Engine())).build(passwdChars),
|
new CBCBlockCipher(new RC2Engine())).build(passwdChars), certs);
|
||||||
certs);
|
|
||||||
pfxPduBuilder.addData(keyBagBuilder.build());
|
pfxPduBuilder.addData(keyBagBuilder.build());
|
||||||
return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwdChars);
|
return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwdChars);
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,7 @@ public class SM2Pkcs12Maker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param privKey 用户私钥
|
* @param privKey 用户私钥
|
||||||
* @param chain X509证书数组,
|
* @param chain X509证书数组, 第一个(index 0)为privKey对应的证书,index i+1 是index i的CA证书
|
||||||
* 第一个(index 0)为privKey对应的证书,index i+1 是index i的CA证书
|
|
||||||
* @param passwd 口令
|
* @param passwd 口令
|
||||||
* @return the PKCS#12 keystore
|
* @return the PKCS#12 keystore
|
||||||
* @throws NoSuchProviderException
|
* @throws NoSuchProviderException
|
||||||
@ -24,8 +23,8 @@ public class SM2Pkcs12Maker {
|
|||||||
* @throws PKCSException
|
* @throws PKCSException
|
||||||
*/
|
*/
|
||||||
public KeyStore makePkcs12(PrivateKey privKey, X509Certificate[] chain, char[] passwd)
|
public KeyStore makePkcs12(PrivateKey privKey, X509Certificate[] chain, char[] passwd)
|
||||||
throws KeyStoreException, NoSuchProviderException,
|
throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException,
|
||||||
NoSuchAlgorithmException, CertificateException, IOException {
|
CertificateException, IOException {
|
||||||
KeyStore ks = KeyStore.getInstance("PKCS12", "BC");
|
KeyStore ks = KeyStore.getInstance("PKCS12", "BC");
|
||||||
ks.load(null, passwd);
|
ks.load(null, passwd);
|
||||||
ks.setKeyEntry("User Key", privKey, passwd, chain);
|
ks.setKeyEntry("User Key", privKey, passwd, chain);
|
||||||
@ -42,8 +41,8 @@ public class SM2Pkcs12Maker {
|
|||||||
* @throws PKCSException
|
* @throws PKCSException
|
||||||
*/
|
*/
|
||||||
public KeyStore makePkcs12(PrivateKey privKey, X509Certificate cert, char[] passwd)
|
public KeyStore makePkcs12(PrivateKey privKey, X509Certificate cert, char[] passwd)
|
||||||
throws KeyStoreException, NoSuchProviderException,
|
throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException,
|
||||||
NoSuchAlgorithmException, CertificateException, IOException {
|
CertificateException, IOException {
|
||||||
return makePkcs12(privKey, new X509Certificate[] {cert}, passwd);
|
return makePkcs12(privKey, new X509Certificate[] {cert}, passwd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@ public class SM2PrivateKey extends BCECPrivateKey {
|
|||||||
|
|
||||||
public SM2PrivateKey(BCECPrivateKey privateKey, BCECPublicKey publicKey) {
|
public SM2PrivateKey(BCECPrivateKey privateKey, BCECPublicKey publicKey) {
|
||||||
super(privateKey.getAlgorithm(), privateKey);
|
super(privateKey.getAlgorithm(), privateKey);
|
||||||
this.sm2PublicKey = getSM2PublicKeyDetails(new SM2PublicKey(publicKey.getAlgorithm(), publicKey));
|
this.sm2PublicKey =
|
||||||
|
getSM2PublicKeyDetails(new SM2PublicKey(publicKey.getAlgorithm(), publicKey));
|
||||||
this.withCompression = false;
|
this.withCompression = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,8 +34,8 @@ public class SM2PrivateKey extends BCECPrivateKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a PKCS8 representation of the key. The sequence returned
|
* Return a PKCS8 representation of the key. The sequence returned represents a full
|
||||||
* represents a full PrivateKeyInfo object.
|
* PrivateKeyInfo object.
|
||||||
*
|
*
|
||||||
* @return a PKCS8 representation of the key.
|
* @return a PKCS8 representation of the key.
|
||||||
*/
|
*/
|
||||||
@ -48,20 +49,25 @@ public class SM2PrivateKey extends BCECPrivateKey {
|
|||||||
if (ecSpec == null) {
|
if (ecSpec == null) {
|
||||||
orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
|
orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS());
|
||||||
} else {
|
} else {
|
||||||
orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
|
orderBitLength =
|
||||||
|
ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS());
|
||||||
}
|
}
|
||||||
|
|
||||||
PrivateKeyInfo info;
|
PrivateKeyInfo info;
|
||||||
org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
|
org.bouncycastle.asn1.sec.ECPrivateKey keyStructure;
|
||||||
|
|
||||||
if (sm2PublicKey != null) {
|
if (sm2PublicKey != null) {
|
||||||
keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), sm2PublicKey, params);
|
keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(),
|
||||||
|
sm2PublicKey, params);
|
||||||
} else {
|
} else {
|
||||||
keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
|
keyStructure =
|
||||||
|
new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
info = new PrivateKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params), keyStructure);
|
info = new PrivateKeyInfo(
|
||||||
|
new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, params),
|
||||||
|
keyStructure);
|
||||||
|
|
||||||
return info.getEncoded(ASN1Encoding.DER);
|
return info.getEncoded(ASN1Encoding.DER);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -71,7 +77,8 @@ public class SM2PrivateKey extends BCECPrivateKey {
|
|||||||
|
|
||||||
private DERBitString getSM2PublicKeyDetails(SM2PublicKey pub) {
|
private DERBitString getSM2PublicKeyDetails(SM2PublicKey pub) {
|
||||||
try {
|
try {
|
||||||
SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded()));
|
SubjectPublicKeyInfo info =
|
||||||
|
SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded()));
|
||||||
|
|
||||||
return info.getPublicKeyData();
|
return info.getPublicKeyData();
|
||||||
} catch (IOException e) { // should never happen
|
} catch (IOException e) { // should never happen
|
||||||
|
@ -10,7 +10,8 @@ import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
|
|||||||
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
|
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
|
||||||
|
|
||||||
public class SM2PublicKey extends BCECPublicKey {
|
public class SM2PublicKey extends BCECPublicKey {
|
||||||
public static final ASN1ObjectIdentifier ID_SM2_PUBKEY_PARAM = new ASN1ObjectIdentifier("1.2.156.10197.1.301");
|
public static final ASN1ObjectIdentifier ID_SM2_PUBKEY_PARAM =
|
||||||
|
new ASN1ObjectIdentifier("1.2.156.10197.1.301");
|
||||||
|
|
||||||
private boolean withCompression;
|
private boolean withCompression;
|
||||||
|
|
||||||
@ -26,8 +27,8 @@ public class SM2PublicKey extends BCECPublicKey {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] getEncoded() {
|
public byte[] getEncoded() {
|
||||||
ASN1OctetString p = ASN1OctetString.getInstance(
|
ASN1OctetString p = ASN1OctetString
|
||||||
new X9ECPoint(getQ(), withCompression).toASN1Primitive());
|
.getInstance(new X9ECPoint(getQ(), withCompression).toASN1Primitive());
|
||||||
|
|
||||||
// stored curve is null if ImplicitlyCa
|
// stored curve is null if ImplicitlyCa
|
||||||
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
|
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
|
||||||
|
@ -28,9 +28,7 @@ import java.util.List;
|
|||||||
public class SM2X509CertMaker {
|
public class SM2X509CertMaker {
|
||||||
|
|
||||||
private static enum CertLevel {
|
private static enum CertLevel {
|
||||||
RootCA,
|
RootCA, SubCA, EndEntity
|
||||||
SubCA,
|
|
||||||
EndEntity
|
|
||||||
} // class CertLevel
|
} // class CertLevel
|
||||||
|
|
||||||
public static final String SIGN_ALGO_SM3WITHSM2 = "SM3withSM2";
|
public static final String SIGN_ALGO_SM3WITHSM2 = "SM3withSM2";
|
||||||
@ -41,9 +39,7 @@ public class SM2X509CertMaker {
|
|||||||
private KeyPair issuerKeyPair;
|
private KeyPair issuerKeyPair;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param issuerKeyPair 证书颁发者的密钥对。
|
* @param issuerKeyPair 证书颁发者的密钥对。 其实一般的CA的私钥都是要严格保护的。 一般CA的私钥都会放在加密卡/加密机里,证书的签名由加密卡/加密机完成。
|
||||||
* 其实一般的CA的私钥都是要严格保护的。
|
|
||||||
* 一般CA的私钥都会放在加密卡/加密机里,证书的签名由加密卡/加密机完成。
|
|
||||||
* 这里仅是为了演示BC库签发证书的用法,所以暂时不作太多要求。
|
* 这里仅是为了演示BC库签发证书的用法,所以暂时不作太多要求。
|
||||||
* @param certExpire 证书有效时间,单位毫秒
|
* @param certExpire 证书有效时间,单位毫秒
|
||||||
* @param issuer 证书颁发者信息
|
* @param issuer 证书颁发者信息
|
||||||
@ -64,8 +60,7 @@ public class SM2X509CertMaker {
|
|||||||
* @return 新的证书
|
* @return 新的证书
|
||||||
* @throws Exception 如果错误发生
|
* @throws Exception 如果错误发生
|
||||||
*/
|
*/
|
||||||
public X509Certificate makeRootCACert(byte[] csr)
|
public X509Certificate makeRootCACert(byte[] csr) throws Exception {
|
||||||
throws Exception {
|
|
||||||
KeyUsage usage = new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign);
|
KeyUsage usage = new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign);
|
||||||
return makeCertificate(CertLevel.RootCA, null, csr, usage, null);
|
return makeCertificate(CertLevel.RootCA, null, csr, usage, null);
|
||||||
}
|
}
|
||||||
@ -77,8 +72,7 @@ public class SM2X509CertMaker {
|
|||||||
* @return 新的证书
|
* @return 新的证书
|
||||||
* @throws Exception 如果错误发生
|
* @throws Exception 如果错误发生
|
||||||
*/
|
*/
|
||||||
public X509Certificate makeSubCACert(byte[] csr)
|
public X509Certificate makeSubCACert(byte[] csr) throws Exception {
|
||||||
throws Exception {
|
|
||||||
KeyUsage usage = new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign);
|
KeyUsage usage = new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign);
|
||||||
return makeCertificate(CertLevel.SubCA, 0, csr, usage, null);
|
return makeCertificate(CertLevel.SubCA, 0, csr, usage, null);
|
||||||
}
|
}
|
||||||
@ -90,8 +84,7 @@ public class SM2X509CertMaker {
|
|||||||
* @return 新的证书
|
* @return 新的证书
|
||||||
* @throws Exception 如果错误发生
|
* @throws Exception 如果错误发生
|
||||||
*/
|
*/
|
||||||
public X509Certificate makeSSLEndEntityCert(byte[] csr)
|
public X509Certificate makeSSLEndEntityCert(byte[] csr) throws Exception {
|
||||||
throws Exception {
|
|
||||||
return makeEndEntityCert(csr,
|
return makeEndEntityCert(csr,
|
||||||
new KeyPurposeId[] {KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth});
|
new KeyPurposeId[] {KeyPurposeId.id_kp_clientAuth, KeyPurposeId.id_kp_serverAuth});
|
||||||
}
|
}
|
||||||
@ -104,8 +97,7 @@ public class SM2X509CertMaker {
|
|||||||
* @return 新的证书
|
* @return 新的证书
|
||||||
* @throws Exception 如果错误发生
|
* @throws Exception 如果错误发生
|
||||||
*/
|
*/
|
||||||
public X509Certificate makeEndEntityCert(byte[] csr,
|
public X509Certificate makeEndEntityCert(byte[] csr, KeyPurposeId[] extendedKeyUsages)
|
||||||
KeyPurposeId[] extendedKeyUsages)
|
|
||||||
throws Exception {
|
throws Exception {
|
||||||
KeyUsage usage = new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyAgreement
|
KeyUsage usage = new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyAgreement
|
||||||
| KeyUsage.dataEncipherment | KeyUsage.keyEncipherment);
|
| KeyUsage.dataEncipherment | KeyUsage.keyEncipherment);
|
||||||
@ -120,8 +112,7 @@ public class SM2X509CertMaker {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
private X509Certificate makeCertificate(CertLevel certLevel, Integer pathLenConstrain,
|
private X509Certificate makeCertificate(CertLevel certLevel, Integer pathLenConstrain,
|
||||||
byte[] csr, KeyUsage keyUsage, KeyPurposeId[] extendedKeyUsages)
|
byte[] csr, KeyUsage keyUsage, KeyPurposeId[] extendedKeyUsages) throws Exception {
|
||||||
throws Exception {
|
|
||||||
if (certLevel == CertLevel.EndEntity) {
|
if (certLevel == CertLevel.EndEntity) {
|
||||||
if (keyUsage.hasUsages(KeyUsage.keyCertSign)) {
|
if (keyUsage.hasUsages(KeyUsage.keyCertSign)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
@ -139,13 +130,11 @@ public class SM2X509CertMaker {
|
|||||||
String email = null;
|
String email = null;
|
||||||
String commonName = null;
|
String commonName = null;
|
||||||
/*
|
/*
|
||||||
* RFC 5280 §4.2.1.6 Subject
|
* RFC 5280 §4.2.1.6 Subject Conforming implementations generating new certificates with
|
||||||
* Conforming implementations generating new certificates with
|
* electronic mail addresses MUST use the rfc822Name in the subject alternative name
|
||||||
* electronic mail addresses MUST use the rfc822Name in the subject
|
* extension (Section 4.2.1.6) to describe such identities. Simultaneous inclusion of the
|
||||||
* alternative name extension (Section 4.2.1.6) to describe such
|
* emailAddress attribute in the subject distinguished name to support legacy
|
||||||
* identities. Simultaneous inclusion of the emailAddress attribute in
|
* implementations is deprecated but permitted.
|
||||||
* the subject distinguished name to support legacy implementations is
|
|
||||||
* deprecated but permitted.
|
|
||||||
*/
|
*/
|
||||||
RDN[] rdns = subject.getRDNs();
|
RDN[] rdns = subject.getRDNs();
|
||||||
List<RDN> newRdns = new ArrayList<>(rdns.length);
|
List<RDN> newRdns = new ArrayList<>(rdns.length);
|
||||||
@ -167,9 +156,8 @@ public class SM2X509CertMaker {
|
|||||||
List<GeneralName> subjectAltNames = new LinkedList<>();
|
List<GeneralName> subjectAltNames = new LinkedList<>();
|
||||||
if (email != null) {
|
if (email != null) {
|
||||||
subject = new X500Name(newRdns.toArray(new RDN[0]));
|
subject = new X500Name(newRdns.toArray(new RDN[0]));
|
||||||
subjectAltNames.add(
|
subjectAltNames
|
||||||
new GeneralName(GeneralName.rfc822Name,
|
.add(new GeneralName(GeneralName.rfc822Name, new DERIA5String(email, true)));
|
||||||
new DERIA5String(email, true)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean selfSignedEECert = false;
|
boolean selfSignedEECert = false;
|
||||||
@ -178,7 +166,8 @@ public class SM2X509CertMaker {
|
|||||||
if (issuerDN.equals(subject)) {
|
if (issuerDN.equals(subject)) {
|
||||||
subject = issuerDN;
|
subject = issuerDN;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("subject != issuer for certLevel " + CertLevel.RootCA);
|
throw new IllegalArgumentException(
|
||||||
|
"subject != issuer for certLevel " + CertLevel.RootCA);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SubCA:
|
case SubCA:
|
||||||
@ -197,17 +186,16 @@ public class SM2X509CertMaker {
|
|||||||
BigInteger serialNumber = snAllocator.nextSerialNumber();
|
BigInteger serialNumber = snAllocator.nextSerialNumber();
|
||||||
Date notBefore = new Date();
|
Date notBefore = new Date();
|
||||||
Date notAfter = new Date(notBefore.getTime() + certExpire);
|
Date notAfter = new Date(notBefore.getTime() + certExpire);
|
||||||
X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(
|
X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(issuerDN, serialNumber,
|
||||||
issuerDN, serialNumber,
|
notBefore, notAfter, subject, subPub);
|
||||||
notBefore, notAfter,
|
|
||||||
subject, subPub);
|
|
||||||
|
|
||||||
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
|
JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();
|
||||||
v3CertGen.addExtension(Extension.subjectKeyIdentifier, false,
|
v3CertGen.addExtension(Extension.subjectKeyIdentifier, false,
|
||||||
extUtils.createSubjectKeyIdentifier(subPub));
|
extUtils.createSubjectKeyIdentifier(subPub));
|
||||||
if (certLevel != CertLevel.RootCA && !selfSignedEECert) {
|
if (certLevel != CertLevel.RootCA && !selfSignedEECert) {
|
||||||
v3CertGen.addExtension(Extension.authorityKeyIdentifier, false,
|
v3CertGen.addExtension(Extension.authorityKeyIdentifier, false,
|
||||||
extUtils.createAuthorityKeyIdentifier(SubjectPublicKeyInfo.getInstance(issPub.getEncoded())));
|
extUtils.createAuthorityKeyIdentifier(
|
||||||
|
SubjectPublicKeyInfo.getInstance(issPub.getEncoded())));
|
||||||
}
|
}
|
||||||
|
|
||||||
// RFC 5280 §4.2.1.9 Basic Constraints:
|
// RFC 5280 §4.2.1.9 Basic Constraints:
|
||||||
@ -219,12 +207,13 @@ public class SM2X509CertMaker {
|
|||||||
if (certLevel == CertLevel.EndEntity) {
|
if (certLevel == CertLevel.EndEntity) {
|
||||||
basicConstraints = new BasicConstraints(false);
|
basicConstraints = new BasicConstraints(false);
|
||||||
} else {
|
} else {
|
||||||
basicConstraints = pathLenConstrain == null
|
basicConstraints = pathLenConstrain == null ? new BasicConstraints(true)
|
||||||
? new BasicConstraints(true) : new BasicConstraints(pathLenConstrain.intValue());
|
: new BasicConstraints(pathLenConstrain.intValue());
|
||||||
}
|
}
|
||||||
v3CertGen.addExtension(Extension.basicConstraints, true, basicConstraints);
|
v3CertGen.addExtension(Extension.basicConstraints, true, basicConstraints);
|
||||||
|
|
||||||
// RFC 5280 §4.2.1.3 Key Usage: When present, conforming CAs SHOULD mark this extension as critical.
|
// RFC 5280 §4.2.1.3 Key Usage: When present, conforming CAs SHOULD mark this extension as
|
||||||
|
// critical.
|
||||||
v3CertGen.addExtension(Extension.keyUsage, true, keyUsage);
|
v3CertGen.addExtension(Extension.keyUsage, true, keyUsage);
|
||||||
|
|
||||||
if (extendedKeyUsages != null) {
|
if (extendedKeyUsages != null) {
|
||||||
@ -243,8 +232,8 @@ public class SM2X509CertMaker {
|
|||||||
if (commonName == null) {
|
if (commonName == null) {
|
||||||
throw new IllegalArgumentException("commonName must not be null");
|
throw new IllegalArgumentException("commonName must not be null");
|
||||||
}
|
}
|
||||||
GeneralName name = new GeneralName(GeneralName.dNSName,
|
GeneralName name =
|
||||||
new DERIA5String(commonName, true));
|
new GeneralName(GeneralName.dNSName, new DERIA5String(commonName, true));
|
||||||
subjectAltNames.add(name);
|
subjectAltNames.add(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +244,8 @@ public class SM2X509CertMaker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JcaContentSignerBuilder contentSignerBuilder = makeContentSignerBuilder(issPub);
|
JcaContentSignerBuilder contentSignerBuilder = makeContentSignerBuilder(issPub);
|
||||||
X509Certificate cert = new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME)
|
X509Certificate cert =
|
||||||
|
new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME)
|
||||||
.getCertificate(v3CertGen.build(contentSignerBuilder.build(issPriv)));
|
.getCertificate(v3CertGen.build(contentSignerBuilder.build(issPriv)));
|
||||||
cert.verify(issPub);
|
cert.verify(issPub);
|
||||||
|
|
||||||
@ -264,7 +254,8 @@ public class SM2X509CertMaker {
|
|||||||
|
|
||||||
private JcaContentSignerBuilder makeContentSignerBuilder(PublicKey issPub) throws Exception {
|
private JcaContentSignerBuilder makeContentSignerBuilder(PublicKey issPub) throws Exception {
|
||||||
if (issPub.getAlgorithm().equals("EC")) {
|
if (issPub.getAlgorithm().equals("EC")) {
|
||||||
JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder(SIGN_ALGO_SM3WITHSM2);
|
JcaContentSignerBuilder contentSignerBuilder =
|
||||||
|
new JcaContentSignerBuilder(SIGN_ALGO_SM3WITHSM2);
|
||||||
contentSignerBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME);
|
contentSignerBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME);
|
||||||
return contentSignerBuilder;
|
return contentSignerBuilder;
|
||||||
}
|
}
|
||||||
|
26
src/main/java/org/paillier/PaillierCipher.java
Executable file → Normal file
26
src/main/java/org/paillier/PaillierCipher.java
Executable file → Normal file
@ -37,8 +37,8 @@ public class PaillierCipher {
|
|||||||
byte[] data = new byte[nLenBytes.length + nBytes.length + cipherBytes.length];
|
byte[] data = new byte[nLenBytes.length + nBytes.length + cipherBytes.length];
|
||||||
System.arraycopy(nLenBytes, 0, data, 0, nLenBytes.length);
|
System.arraycopy(nLenBytes, 0, data, 0, nLenBytes.length);
|
||||||
System.arraycopy(nBytes, 0, data, nLenBytes.length, nBytes.length);
|
System.arraycopy(nBytes, 0, data, nLenBytes.length, nBytes.length);
|
||||||
System.arraycopy(
|
System.arraycopy(cipherBytes, 0, data, nLenBytes.length + nBytes.length,
|
||||||
cipherBytes, 0, data, nLenBytes.length + nBytes.length, cipherBytes.length);
|
cipherBytes.length);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,10 +49,7 @@ public class PaillierCipher {
|
|||||||
public static BigInteger decrypt(byte[] ciphertext, PrivateKey privateKey) {
|
public static BigInteger decrypt(byte[] ciphertext, PrivateKey privateKey) {
|
||||||
RSAPrivateCrtKey rsaPriKey = (RSAPrivateCrtKey) privateKey;
|
RSAPrivateCrtKey rsaPriKey = (RSAPrivateCrtKey) privateKey;
|
||||||
BigInteger n = rsaPriKey.getModulus();
|
BigInteger n = rsaPriKey.getModulus();
|
||||||
BigInteger lambda =
|
BigInteger lambda = rsaPriKey.getPrimeP().subtract(BigInteger.ONE)
|
||||||
rsaPriKey
|
|
||||||
.getPrimeP()
|
|
||||||
.subtract(BigInteger.ONE)
|
|
||||||
.multiply(rsaPriKey.getPrimeQ().subtract(BigInteger.ONE));
|
.multiply(rsaPriKey.getPrimeQ().subtract(BigInteger.ONE));
|
||||||
|
|
||||||
int nLen = CommonUtils.byte2ToUnsignedShort(ciphertext);
|
int nLen = CommonUtils.byte2ToUnsignedShort(ciphertext);
|
||||||
@ -70,13 +67,8 @@ public class PaillierCipher {
|
|||||||
|
|
||||||
BigInteger mu = lambda.modInverse(n);
|
BigInteger mu = lambda.modInverse(n);
|
||||||
BigInteger nsquare = n.multiply(n);
|
BigInteger nsquare = n.multiply(n);
|
||||||
BigInteger message =
|
BigInteger message = intCiphertext.modPow(lambda, nsquare).subtract(BigInteger.ONE)
|
||||||
intCiphertext
|
.divide(n).multiply(mu).mod(n);
|
||||||
.modPow(lambda, nsquare)
|
|
||||||
.subtract(BigInteger.ONE)
|
|
||||||
.divide(n)
|
|
||||||
.multiply(mu)
|
|
||||||
.mod(n);
|
|
||||||
BigInteger maxValue = BigInteger.ONE.shiftLeft(n.bitLength() / 2);
|
BigInteger maxValue = BigInteger.ONE.shiftLeft(n.bitLength() / 2);
|
||||||
if (message.compareTo(maxValue) > 0) {
|
if (message.compareTo(maxValue) > 0) {
|
||||||
return message.subtract(n);
|
return message.subtract(n);
|
||||||
@ -86,9 +78,7 @@ public class PaillierCipher {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static String ciphertextAdd(String ciphertext1, String ciphertext2) {
|
public static String ciphertextAdd(String ciphertext1, String ciphertext2) {
|
||||||
return CommonUtils.byteToHexString(
|
return CommonUtils.byteToHexString(ciphertextAdd(CommonUtils.hexStringToBytes(ciphertext1),
|
||||||
ciphertextAdd(
|
|
||||||
CommonUtils.hexStringToBytes(ciphertext1),
|
|
||||||
CommonUtils.hexStringToBytes(ciphertext2)));
|
CommonUtils.hexStringToBytes(ciphertext2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,8 +112,8 @@ public class PaillierCipher {
|
|||||||
byte[] data = new byte[nLenBytes.length + nBytes1.length + cipherBytes.length];
|
byte[] data = new byte[nLenBytes.length + nBytes1.length + cipherBytes.length];
|
||||||
System.arraycopy(nLenBytes, 0, data, 0, nLenBytes.length);
|
System.arraycopy(nLenBytes, 0, data, 0, nLenBytes.length);
|
||||||
System.arraycopy(nBytes1, 0, data, nLenBytes.length, nBytes1.length);
|
System.arraycopy(nBytes1, 0, data, nLenBytes.length, nBytes1.length);
|
||||||
System.arraycopy(
|
System.arraycopy(cipherBytes, 0, data, nLenBytes.length + nBytes1.length,
|
||||||
cipherBytes, 0, data, nLenBytes.length + nBytes1.length, cipherBytes.length);
|
cipherBytes.length);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
8
src/test/java/org/paillier/PaillierTest.java
Executable file → Normal file
8
src/test/java/org/paillier/PaillierTest.java
Executable file → Normal file
@ -2,8 +2,6 @@ package org.paillier;
|
|||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.paillier.PaillierCipher;
|
|
||||||
import org.paillier.PaillierKeyPair;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
@ -62,8 +60,7 @@ public class PaillierTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void decryptTest() {
|
public void decryptTest() {
|
||||||
String privateKeyStr =
|
String privateKeyStr = "-----BEGIN PRIVATE KEY-----\n"
|
||||||
"-----BEGIN PRIVATE KEY-----\n"
|
|
||||||
+ "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1f/Oa//I+SFNN\n"
|
+ "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1f/Oa//I+SFNN\n"
|
||||||
+ "v+PmHGJ1vLGFDu6A0IQV9DcX/hf2R2JFW/ONxfjlrtAh4dW7itMwIA6u64UlKiml\n"
|
+ "v+PmHGJ1vLGFDu6A0IQV9DcX/hf2R2JFW/ONxfjlrtAh4dW7itMwIA6u64UlKiml\n"
|
||||||
+ "4UuVBT9ca4wv7R87DFqhxquh+ObMzo2x6QAaXnvL5WMmu8+/aLg6Nc06BXtJHsiw\n"
|
+ "4UuVBT9ca4wv7R87DFqhxquh+ObMzo2x6QAaXnvL5WMmu8+/aLg6Nc06BXtJHsiw\n"
|
||||||
@ -89,8 +86,7 @@ public class PaillierTest {
|
|||||||
+ "pue4kqTPW1Vxdjh6CA/Hb7VHBT/hbdAT1fI7WCgBAoGAZq1rFESL3roi8DtOWl51\n"
|
+ "pue4kqTPW1Vxdjh6CA/Hb7VHBT/hbdAT1fI7WCgBAoGAZq1rFESL3roi8DtOWl51\n"
|
||||||
+ "nduNO20Yloe6tlhUAKo63krRHKBeKTyLXycpZHcq6UEfys3dixFfu0lN6002lUku\n"
|
+ "nduNO20Yloe6tlhUAKo63krRHKBeKTyLXycpZHcq6UEfys3dixFfu0lN6002lUku\n"
|
||||||
+ "MTbmNOJWhOCa2xuZY0CeINKFnKBnbiauBpo6x+2J0PoWFn8wd1tzFJPbodk8Km1f\n"
|
+ "MTbmNOJWhOCa2xuZY0CeINKFnKBnbiauBpo6x+2J0PoWFn8wd1tzFJPbodk8Km1f\n"
|
||||||
+ "qySov+6mrQxHojQYBu9/yYQ=\n"
|
+ "qySov+6mrQxHojQYBu9/yYQ=\n" + "-----END PRIVATE KEY-----";
|
||||||
+ "-----END PRIVATE KEY-----";
|
|
||||||
|
|
||||||
String cipher =
|
String cipher =
|
||||||
"0100B57FF39AFFF23E48534DBFE3E61C6275BCB1850EEE80D08415F43717FE17F64762455BF38DC5F8E5AED021E1D5BB8AD330200EAEEB85252A29A5E14B95053F5C6B8C2FED1F3B0C5AA1C6ABA1F8E6CCCE8DB1E9001A5E7BCBE56326BBCFBF68B83A35CD3A057B491EC8B04CEEC1D3D01C0CD71C743C88FA05CFE0B12C22887D1D1D69E3572AD5129EE5CF6484BAF2739CD0A9FE8D5A5C38696AFD008E70E26EF386C4E20C7D51F6A2D226E80E96D63EF612C5EC4F4B7B130BC17A10518CA2D161B145ED21D37F8442CCEFE20400E296893C09E4F24E95AD4C9394175EA189DE227C59D0512D15F7E4FEBA95B7807CD238D54536E579298336F6FB285A7E2874AB6914BF4FF089BFD98EC18D9E8B3D7FB2F5CFC20715C62D34F08E36D84F2CDABA2D1A1798C95161B7831167ED27E8894F1EB25D4E74DF382BF276D9ACBEADB56795F3DF8A4E6CE9DF7B6CFEFD5C66F0BC45D24CCC8E8095A7BF5CE69FEC5579B874A4C9B7C8F13126EC59D7C6DF0404816F638C7D4A84FE038E6F00B5667AC88E4307990E4C06B3864D86B7349275B20A3FB50FBA64706F214CC642219DCEF4453C30B89790F6FB1566A5D557AD7EC5890CA50E80111319F9742943FBD675D18753E5ABD21941832A11332ED902C334309E3770512AC042E1556C3F0ECCFC056C66D7362BA4E7896EA0807412817C68D7B5434AFA0D95A12B950573994F081F996545B871E485C392288E2D61C3B0CBB9FC4E68C1C558A598B03BACFF27967BE8AEA8F1322EC3E0957A3ED84810164A59BDEE2D1514EA68228CB96B59D8BA1E9234A24D57E5F8D7E55724EF0AE9D83F6E2A84B9A1E47B59091201B1B65542BBBB5A988CBBD5395335C4DF821ACEF289D20444B74CABC406A7C4F810EFF85838994DBDD38EDF74D4821153A5128AB98C15409C73891415B194803B3ABF761CEE57D1F58813A7125260E58864970CA2650E0D46C239ED92FCC3491C5FA372838B475D14E4946FCC3C421A76C434C5310D1A17A744551CFB5F99547BB216AD7C1ADA5C27CA64B34C29152D29B0A4B90B0C72A7A18BD19CF278B6F39186A39F91FB4D";
|
"0100B57FF39AFFF23E48534DBFE3E61C6275BCB1850EEE80D08415F43717FE17F64762455BF38DC5F8E5AED021E1D5BB8AD330200EAEEB85252A29A5E14B95053F5C6B8C2FED1F3B0C5AA1C6ABA1F8E6CCCE8DB1E9001A5E7BCBE56326BBCFBF68B83A35CD3A057B491EC8B04CEEC1D3D01C0CD71C743C88FA05CFE0B12C22887D1D1D69E3572AD5129EE5CF6484BAF2739CD0A9FE8D5A5C38696AFD008E70E26EF386C4E20C7D51F6A2D226E80E96D63EF612C5EC4F4B7B130BC17A10518CA2D161B145ED21D37F8442CCEFE20400E296893C09E4F24E95AD4C9394175EA189DE227C59D0512D15F7E4FEBA95B7807CD238D54536E579298336F6FB285A7E2874AB6914BF4FF089BFD98EC18D9E8B3D7FB2F5CFC20715C62D34F08E36D84F2CDABA2D1A1798C95161B7831167ED27E8894F1EB25D4E74DF382BF276D9ACBEADB56795F3DF8A4E6CE9DF7B6CFEFD5C66F0BC45D24CCC8E8095A7BF5CE69FEC5579B874A4C9B7C8F13126EC59D7C6DF0404816F638C7D4A84FE038E6F00B5667AC88E4307990E4C06B3864D86B7349275B20A3FB50FBA64706F214CC642219DCEF4453C30B89790F6FB1566A5D557AD7EC5890CA50E80111319F9742943FBD675D18753E5ABD21941832A11332ED902C334309E3770512AC042E1556C3F0ECCFC056C66D7362BA4E7896EA0807412817C68D7B5434AFA0D95A12B950573994F081F996545B871E485C392288E2D61C3B0CBB9FC4E68C1C558A598B03BACFF27967BE8AEA8F1322EC3E0957A3ED84810164A59BDEE2D1514EA68228CB96B59D8BA1E9234A24D57E5F8D7E55724EF0AE9D83F6E2A84B9A1E47B59091201B1B65542BBBB5A988CBBD5395335C4DF821ACEF289D20444B74CABC406A7C4F810EFF85838994DBDD38EDF74D4821153A5128AB98C15409C73891415B194803B3ABF761CEE57D1F58813A7125260E58864970CA2650E0D46C239ED92FCC3491C5FA372838B475D14E4946FCC3C421A76C434C5310D1A17A744551CFB5F99547BB216AD7C1ADA5C27CA64B34C29152D29B0A4B90B0C72A7A18BD19CF278B6F39186A39F91FB4D";
|
||||||
|
Loading…
Reference in New Issue
Block a user