mirror of
				https://gitee.com/BDWare/gmhelper
				synced 2025-10-31 12:42:15 +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(); | ||||||
|     } |     } | ||||||
| @ -93,32 +90,32 @@ public class BCECUtil { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param dHex             十六进制字符串形式的私钥d值,如果是SM2算法,Hex字符串长度应该是64(即32字节) |      * @param dHex 十六进制字符串形式的私钥d值,如果是SM2算法,Hex字符串长度应该是64(即32字节) | ||||||
|      * @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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param dBytes           字节数组形式的私钥d值,如果是SM2算法,应该是32字节 |      * @param dBytes 字节数组形式的私钥d值,如果是SM2算法,应该是32字节 | ||||||
|      * @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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param d                大数形式的私钥d值 |      * @param d 大数形式的私钥d值 | ||||||
|      * @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,46 +125,48 @@ 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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param x                大数形式的公钥x分量 |      * @param x 大数形式的公钥x分量 | ||||||
|      * @param y                大数形式的公钥y分量 |      * @param y 大数形式的公钥y分量 | ||||||
|      * @param curve            EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} |      * @param curve EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||||
|      * @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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param xHex             十六进制形式的公钥x分量,如果是SM2算法,Hex字符串长度应该是64(即32字节) |      * @param xHex 十六进制形式的公钥x分量,如果是SM2算法,Hex字符串长度应该是64(即32字节) | ||||||
|      * @param yHex             十六进制形式的公钥y分量,如果是SM2算法,Hex字符串长度应该是64(即32字节) |      * @param yHex 十六进制形式的公钥y分量,如果是SM2算法,Hex字符串长度应该是64(即32字节) | ||||||
|      * @param curve            EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} |      * @param curve EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||||
|      * @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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param xBytes           十六进制形式的公钥x分量,如果是SM2算法,应该是32字节 |      * @param xBytes 十六进制形式的公钥x分量,如果是SM2算法,应该是32字节 | ||||||
|      * @param yBytes           十六进制形式的公钥y分量,如果是SM2算法,应该是32字节 |      * @param yBytes 十六进制形式的公钥y分量,如果是SM2算法,应该是32字节 | ||||||
|      * @param curve            EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} |      * @param curve EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||||
|      * @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); | ||||||
| @ -180,44 +179,35 @@ public class BCECUtil { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param str              十六进制形式的公钥x分量,如果是SM2算法,应该是32字节 |      * @param str 十六进制形式的公钥x分量,如果是SM2算法,应该是32字节 | ||||||
|      * @param curve            EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} |      * @param curve EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||||
|      * @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS} |      * @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS} | ||||||
|      * @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,23 +461,18 @@ 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(), |                     ecSpec.getCurve().getSeed()); | ||||||
|                             BigInteger.valueOf(ecSpec.getCofactor()), |  | ||||||
|                             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); | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -7,51 +7,53 @@ import java.util.Arrays; | |||||||
| 
 | 
 | ||||||
| public class SM2KeyExchangeUtil { | public class SM2KeyExchangeUtil { | ||||||
|     /** |     /** | ||||||
|      * @param initiator         true表示发起方,false表示响应方 |      * @param initiator true表示发起方,false表示响应方 | ||||||
|      * @param keyBits           生成的密钥长度 |      * @param keyBits 生成的密钥长度 | ||||||
|      * @param selfStaticPriv    己方固定私钥 |      * @param selfStaticPriv 己方固定私钥 | ||||||
|      * @param selfEphemeralPriv 己方临时私钥 |      * @param selfEphemeralPriv 己方临时私钥 | ||||||
|      * @param selfId            己方ID |      * @param selfId 己方ID | ||||||
|      * @param otherStaticPub    对方固定公钥 |      * @param otherStaticPub 对方固定公钥 | ||||||
|      * @param otherEphemeralPub 对方临时公钥 |      * @param otherEphemeralPub 对方临时公钥 | ||||||
|      * @param otherId           对方ID |      * @param otherId 对方ID | ||||||
|      * @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)); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param initiator         true表示发起方,false表示响应方 |      * @param initiator true表示发起方,false表示响应方 | ||||||
|      * @param keyBits           生成的密钥长度 |      * @param keyBits 生成的密钥长度 | ||||||
|      * @param confirmationTag   确认信息,如果是响应方可以为null;如果是发起方则应为响应方的s1 |      * @param confirmationTag 确认信息,如果是响应方可以为null;如果是发起方则应为响应方的s1 | ||||||
|      * @param selfStaticPriv    己方固定私钥 |      * @param selfStaticPriv 己方固定私钥 | ||||||
|      * @param selfEphemeralPriv 己方临时私钥 |      * @param selfEphemeralPriv 己方临时私钥 | ||||||
|      * @param selfId            己方ID |      * @param selfId 己方ID | ||||||
|      * @param otherStaticPub    对方固定公钥 |      * @param otherStaticPub 对方固定公钥 | ||||||
|      * @param otherEphemeralPub 对方临时公钥 |      * @param otherEphemeralPub 对方临时公钥 | ||||||
|      * @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,29 +73,16 @@ 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( |                     BouncyCastleProvider.CONFIGURATION); | ||||||
|                             BCECUtil.ALGO_NAME_EC, |  | ||||||
|                             publicKey, |  | ||||||
|                             spec, |  | ||||||
|                             BouncyCastleProvider.CONFIGURATION); |  | ||||||
|         } |         } | ||||||
|         bcPrivateKey = |         bcPrivateKey = new BCECPrivateKey(BCECUtil.ALGO_NAME_EC, privateKey, bcPublicKey, spec, | ||||||
|                 new BCECPrivateKey( |                 BouncyCastleProvider.CONFIGURATION); | ||||||
|                         BCECUtil.ALGO_NAME_EC, |  | ||||||
|                         privateKey, |  | ||||||
|                         bcPublicKey, |  | ||||||
|                         spec, |  | ||||||
|                         BouncyCastleProvider.CONFIGURATION); |  | ||||||
|         return new KeyPair(bcPublicKey, bcPrivateKey); |         return new KeyPair(bcPublicKey, bcPrivateKey); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,7 +20,7 @@ import java.math.BigInteger; | |||||||
|  * 有的国密需求是用户可以自己做预处理,签名验签只是对预处理的结果进行签名和验签 |  * 有的国密需求是用户可以自己做预处理,签名验签只是对预处理的结果进行签名和验签 | ||||||
|  */ |  */ | ||||||
| public class SM2PreprocessSigner implements ECConstants { | public class SM2PreprocessSigner implements ECConstants { | ||||||
|     private static final int DIGEST_LENGTH = 32;   // bytes |     private static final int DIGEST_LENGTH = 32; // bytes | ||||||
| 
 | 
 | ||||||
|     private final DSAKCalculator kCalculator = new RandomDSAKCalculator(); |     private final DSAKCalculator kCalculator = new RandomDSAKCalculator(); | ||||||
|     private Digest digest = null; |     private Digest digest = null; | ||||||
| @ -44,11 +44,12 @@ public class SM2PreprocessSigner implements ECConstants { | |||||||
|      * 初始化 |      * 初始化 | ||||||
|      * |      * | ||||||
|      * @param forSigning true表示用于签名,false表示用于验签 |      * @param forSigning true表示用于签名,false表示用于验签 | ||||||
|      * @param digest     SM2算法的话,一般是采用SM3摘要算法 |      * @param digest SM2算法的话,一般是采用SM3摘要算法 | ||||||
|      * @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 | ||||||
|      */ |      */ | ||||||
| @ -126,7 +125,7 @@ public class SM2PreprocessSigner implements ECConstants { | |||||||
| 
 | 
 | ||||||
|         ECMultiplier basePointMultiplier = createBasePointMultiplier(); |         ECMultiplier basePointMultiplier = createBasePointMultiplier(); | ||||||
| 
 | 
 | ||||||
|         // 5.2.1 Draft RFC:  SM2 Public Key Algorithms |         // 5.2.1 Draft RFC: SM2 Public Key Algorithms | ||||||
|         do // generate s |         do // generate s | ||||||
|         { |         { | ||||||
|             BigInteger k; |             BigInteger k; | ||||||
| @ -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 { | ||||||
| @ -162,7 +159,7 @@ public class SM2PreprocessSigner implements ECConstants { | |||||||
|     private boolean verifySignature(byte[] eHash, BigInteger r, BigInteger s) { |     private boolean verifySignature(byte[] eHash, BigInteger r, BigInteger s) { | ||||||
|         BigInteger n = ecParams.getN(); |         BigInteger n = ecParams.getN(); | ||||||
| 
 | 
 | ||||||
|         // 5.3.1 Draft RFC:  SM2 Public Key Algorithms |         // 5.3.1 Draft RFC: SM2 Public Key Algorithms | ||||||
|         // B1 |         // B1 | ||||||
|         if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) { |         if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) { | ||||||
|             return false; |             return false; | ||||||
| @ -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)); | ||||||
|  | |||||||
| @ -19,195 +19,196 @@ import org.bouncycastle.util.encoders.Hex; | |||||||
| import java.math.BigInteger; | import java.math.BigInteger; | ||||||
| 
 | 
 | ||||||
| public class SM2Signer implements Signer, ECConstants { | public class SM2Signer implements Signer, ECConstants { | ||||||
|   private final DSAKCalculator kCalculator; |     private final DSAKCalculator kCalculator; | ||||||
|   private final Digest digest; |     private final Digest digest; | ||||||
|   private final DSAEncoding encoding; |     private final DSAEncoding encoding; | ||||||
|   private ECDomainParameters ecParams; |     private ECDomainParameters ecParams; | ||||||
|   private ECPoint pubPoint; |     private ECPoint pubPoint; | ||||||
|   private ECKeyParameters ecKey; |     private ECKeyParameters ecKey; | ||||||
|   private byte[] z; |     private byte[] z; | ||||||
| 
 | 
 | ||||||
|   public SM2Signer() { |     public SM2Signer() { | ||||||
|     this(StandardDSAEncoding.INSTANCE, new SM3Digest()); |         this(StandardDSAEncoding.INSTANCE, new SM3Digest()); | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   public SM2Signer(Digest var1) { |  | ||||||
|     this(StandardDSAEncoding.INSTANCE, var1); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   public SM2Signer(DSAEncoding var1) { |  | ||||||
|     this.kCalculator = new RandomDSAKCalculator(); |  | ||||||
|     this.encoding = var1; |  | ||||||
|     this.digest = new SM3Digest(); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   public SM2Signer(DSAEncoding var1, Digest var2) { |  | ||||||
|     this.kCalculator = new RandomDSAKCalculator(); |  | ||||||
|     this.encoding = var1; |  | ||||||
|     this.digest = var2; |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   public void init(boolean var1, CipherParameters var2) { |  | ||||||
|     CipherParameters var3; |  | ||||||
|     byte[] var4; |  | ||||||
|     if (var2 instanceof ParametersWithID) { |  | ||||||
|       var3 = ((ParametersWithID) var2).getParameters(); |  | ||||||
|       var4 = ((ParametersWithID) var2).getID(); |  | ||||||
|       if (var4.length >= 8192) { |  | ||||||
|         throw new IllegalArgumentException("SM2 user ID must be less than 2^16 bits long"); |  | ||||||
|       } |  | ||||||
|     } else { |  | ||||||
|       var3 = var2; |  | ||||||
|       var4 = Hex.decodeStrict("31323334353637383132333435363738"); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (var1) { |     public SM2Signer(Digest var1) { | ||||||
|       if (var3 instanceof ParametersWithRandom) { |         this(StandardDSAEncoding.INSTANCE, var1); | ||||||
|         ParametersWithRandom var5 = (ParametersWithRandom) var3; |  | ||||||
|         this.ecKey = (ECKeyParameters) var5.getParameters(); |  | ||||||
|         this.ecParams = this.ecKey.getParameters(); |  | ||||||
|         this.kCalculator.init(this.ecParams.getN(), var5.getRandom()); |  | ||||||
|       } else { |  | ||||||
|         this.ecKey = (ECKeyParameters) var3; |  | ||||||
|         this.ecParams = this.ecKey.getParameters(); |  | ||||||
|         this.kCalculator.init(this.ecParams.getN(), CryptoServicesRegistrar.getSecureRandom()); |  | ||||||
|       } |  | ||||||
| 
 |  | ||||||
|       this.pubPoint = |  | ||||||
|           this.createBasePointMultiplier() |  | ||||||
|               .multiply(this.ecParams.getG(), ((ECPrivateKeyParameters) this.ecKey).getD()) |  | ||||||
|               .normalize(); |  | ||||||
|     } else { |  | ||||||
|       this.ecKey = (ECKeyParameters) var3; |  | ||||||
|       this.ecParams = this.ecKey.getParameters(); |  | ||||||
|       this.pubPoint = ((ECPublicKeyParameters) this.ecKey).getQ(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     this.z = this.getZ(var4); |     public SM2Signer(DSAEncoding var1) { | ||||||
|     this.digest.update(this.z, 0, this.z.length); |         this.kCalculator = new RandomDSAKCalculator(); | ||||||
|   } |         this.encoding = var1; | ||||||
| 
 |         this.digest = new SM3Digest(); | ||||||
|   public void update(byte var1) { |  | ||||||
|     this.digest.update(var1); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   public void update(byte[] var1, int var2, int var3) { |  | ||||||
|     this.digest.update(var1, var2, var3); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   public boolean verifySignature(byte[] var1) { |  | ||||||
|     try { |  | ||||||
|       BigInteger[] var2 = this.encoding.decode(this.ecParams.getN(), var1); |  | ||||||
|       return this.verifySignature(var2[0], var2[1]); |  | ||||||
|     } catch (Exception var3) { |  | ||||||
|       return false; |  | ||||||
|     } |     } | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   public void reset() { |     public SM2Signer(DSAEncoding var1, Digest var2) { | ||||||
|     this.digest.reset(); |         this.kCalculator = new RandomDSAKCalculator(); | ||||||
|     if (this.z != null) { |         this.encoding = var1; | ||||||
|       this.digest.update(this.z, 0, this.z.length); |         this.digest = var2; | ||||||
|     } |     } | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   public byte[] generateSignature() throws CryptoException { |     public void init(boolean var1, CipherParameters var2) { | ||||||
|     byte[] var1 = this.digestDoFinal(); |         CipherParameters var3; | ||||||
|     BigInteger n = this.ecParams.getN(); |         byte[] var4; | ||||||
|     BigInteger var3 = this.calculateE(n , var1); |         if (var2 instanceof ParametersWithID) { | ||||||
|     BigInteger var4 = ((ECPrivateKeyParameters) this.ecKey).getD(); |             var3 = ((ParametersWithID) var2).getParameters(); | ||||||
|     ECMultiplier var7 = this.createBasePointMultiplier(); |             var4 = ((ParametersWithID) var2).getID(); | ||||||
| 
 |             if (var4.length >= 8192) { | ||||||
|     while (true) { |                 throw new IllegalArgumentException("SM2 user ID must be less than 2^16 bits long"); | ||||||
|       BigInteger var5; |             } | ||||||
|       BigInteger k; |  | ||||||
|       do { |  | ||||||
|         k = this.kCalculator.nextK(); |  | ||||||
|         ECPoint var9 = var7.multiply(this.ecParams.getG(), k).normalize(); |  | ||||||
|         var5 = var3.add(var9.getAffineXCoord().toBigInteger()).mod(n); |  | ||||||
|       } while (var5.equals(ZERO)); |  | ||||||
| 
 |  | ||||||
|       if (!var5.add(k).equals(n )) { |  | ||||||
|         BigInteger var11 = BigIntegers.modOddInverse(n, var4.add(ONE)); |  | ||||||
|         BigInteger var6 = k.subtract(var5.multiply(var4)).mod(n); |  | ||||||
|         var6 = var11.multiply(var6).mod(n); |  | ||||||
|         if (!var6.equals(ZERO)) { |  | ||||||
|           try { |  | ||||||
|             return this.encoding.encode(this.ecParams.getN(), var5, var6); |  | ||||||
|           } catch (Exception var10) { |  | ||||||
|             throw new CryptoException("unable to encode signature: " + var10.getMessage(), var10); |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   private boolean verifySignature(BigInteger var1, BigInteger var2) { |  | ||||||
|     BigInteger var3 = this.ecParams.getN(); |  | ||||||
|     if (var1.compareTo(ONE) >= 0 && var1.compareTo(var3) < 0) { |  | ||||||
|       if (var2.compareTo(ONE) >= 0 && var2.compareTo(var3) < 0) { |  | ||||||
|         byte[] var4 = this.digestDoFinal(); |  | ||||||
|         BigInteger var5 = this.calculateE(var3, var4); |  | ||||||
|         BigInteger var6 = var1.add(var2).mod(var3); |  | ||||||
|         if (var6.equals(ZERO)) { |  | ||||||
|           return false; |  | ||||||
|         } else { |         } else { | ||||||
|           ECPoint var7 = ((ECPublicKeyParameters) this.ecKey).getQ(); |             var3 = var2; | ||||||
|           ECPoint var8 = |             var4 = Hex.decodeStrict("31323334353637383132333435363738"); | ||||||
|               ECAlgorithms.sumOfTwoMultiplies(this.ecParams.getG(), var2, var7, var6).normalize(); |  | ||||||
|           if (var8.isInfinity()) { |  | ||||||
|             return false; |  | ||||||
|           } else { |  | ||||||
|             BigInteger var9 = var5.add(var8.getAffineXCoord().toBigInteger()).mod(var3); |  | ||||||
|             return var9.equals(var1); |  | ||||||
|           } |  | ||||||
|         } |         } | ||||||
|       } else { | 
 | ||||||
|         return false; |         if (var1) { | ||||||
|       } |             if (var3 instanceof ParametersWithRandom) { | ||||||
|     } else { |                 ParametersWithRandom var5 = (ParametersWithRandom) var3; | ||||||
|       return false; |                 this.ecKey = (ECKeyParameters) var5.getParameters(); | ||||||
|  |                 this.ecParams = this.ecKey.getParameters(); | ||||||
|  |                 this.kCalculator.init(this.ecParams.getN(), var5.getRandom()); | ||||||
|  |             } else { | ||||||
|  |                 this.ecKey = (ECKeyParameters) var3; | ||||||
|  |                 this.ecParams = this.ecKey.getParameters(); | ||||||
|  |                 this.kCalculator.init(this.ecParams.getN(), | ||||||
|  |                         CryptoServicesRegistrar.getSecureRandom()); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             this.pubPoint = this.createBasePointMultiplier() | ||||||
|  |                     .multiply(this.ecParams.getG(), ((ECPrivateKeyParameters) this.ecKey).getD()) | ||||||
|  |                     .normalize(); | ||||||
|  |         } else { | ||||||
|  |             this.ecKey = (ECKeyParameters) var3; | ||||||
|  |             this.ecParams = this.ecKey.getParameters(); | ||||||
|  |             this.pubPoint = ((ECPublicKeyParameters) this.ecKey).getQ(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         this.z = this.getZ(var4); | ||||||
|  |         this.digest.update(this.z, 0, this.z.length); | ||||||
|     } |     } | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   private byte[] digestDoFinal() { |     public void update(byte var1) { | ||||||
|     byte[] var1 = new byte[this.digest.getDigestSize()]; |         this.digest.update(var1); | ||||||
|     this.digest.doFinal(var1, 0); |     } | ||||||
|     this.reset(); |  | ||||||
|     return var1; |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   private byte[] getZ(byte[] var1) { |     public void update(byte[] var1, int var2, int var3) { | ||||||
|     this.digest.reset(); |         this.digest.update(var1, var2, var3); | ||||||
|     this.addUserID(this.digest, var1); |     } | ||||||
|     this.addFieldElement(this.digest, this.ecParams.getCurve().getA()); |  | ||||||
|     this.addFieldElement(this.digest, this.ecParams.getCurve().getB()); |  | ||||||
|     this.addFieldElement(this.digest, this.ecParams.getG().getAffineXCoord()); |  | ||||||
|     this.addFieldElement(this.digest, this.ecParams.getG().getAffineYCoord()); |  | ||||||
|     this.addFieldElement(this.digest, this.pubPoint.getAffineXCoord()); |  | ||||||
|     this.addFieldElement(this.digest, this.pubPoint.getAffineYCoord()); |  | ||||||
|     byte[] var2 = new byte[this.digest.getDigestSize()]; |  | ||||||
|     this.digest.doFinal(var2, 0); |  | ||||||
|     return var2; |  | ||||||
|   } |  | ||||||
| 
 | 
 | ||||||
|   private void addUserID(Digest var1, byte[] var2) { |     public boolean verifySignature(byte[] var1) { | ||||||
|     int var3 = var2.length * 8; |         try { | ||||||
|     var1.update((byte) (var3 >> 8 & 255)); |             BigInteger[] var2 = this.encoding.decode(this.ecParams.getN(), var1); | ||||||
|     var1.update((byte) (var3 & 255)); |             return this.verifySignature(var2[0], var2[1]); | ||||||
|     var1.update(var2, 0, var2.length); |         } catch (Exception var3) { | ||||||
|   } |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|   private void addFieldElement(Digest var1, ECFieldElement var2) { |     public void reset() { | ||||||
|     byte[] var3 = var2.getEncoded(); |         this.digest.reset(); | ||||||
|     var1.update(var3, 0, var3.length); |         if (this.z != null) { | ||||||
|   } |             this.digest.update(this.z, 0, this.z.length); | ||||||
|  |         } | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|   protected ECMultiplier createBasePointMultiplier() { |     public byte[] generateSignature() throws CryptoException { | ||||||
|     return new FixedPointCombMultiplier(); |         byte[] var1 = this.digestDoFinal(); | ||||||
|   } |         BigInteger n = this.ecParams.getN(); | ||||||
|  |         BigInteger var3 = this.calculateE(n, var1); | ||||||
|  |         BigInteger var4 = ((ECPrivateKeyParameters) this.ecKey).getD(); | ||||||
|  |         ECMultiplier var7 = this.createBasePointMultiplier(); | ||||||
| 
 | 
 | ||||||
|   protected BigInteger calculateE(BigInteger var1, byte[] var2) { |         while (true) { | ||||||
|     return new BigInteger(1, var2); |             BigInteger var5; | ||||||
|   } |             BigInteger k; | ||||||
|  |             do { | ||||||
|  |                 k = this.kCalculator.nextK(); | ||||||
|  |                 ECPoint var9 = var7.multiply(this.ecParams.getG(), k).normalize(); | ||||||
|  |                 var5 = var3.add(var9.getAffineXCoord().toBigInteger()).mod(n); | ||||||
|  |             } while (var5.equals(ZERO)); | ||||||
|  | 
 | ||||||
|  |             if (!var5.add(k).equals(n)) { | ||||||
|  |                 BigInteger var11 = BigIntegers.modOddInverse(n, var4.add(ONE)); | ||||||
|  |                 BigInteger var6 = k.subtract(var5.multiply(var4)).mod(n); | ||||||
|  |                 var6 = var11.multiply(var6).mod(n); | ||||||
|  |                 if (!var6.equals(ZERO)) { | ||||||
|  |                     try { | ||||||
|  |                         return this.encoding.encode(this.ecParams.getN(), var5, var6); | ||||||
|  |                     } catch (Exception var10) { | ||||||
|  |                         throw new CryptoException( | ||||||
|  |                                 "unable to encode signature: " + var10.getMessage(), var10); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private boolean verifySignature(BigInteger var1, BigInteger var2) { | ||||||
|  |         BigInteger var3 = this.ecParams.getN(); | ||||||
|  |         if (var1.compareTo(ONE) >= 0 && var1.compareTo(var3) < 0) { | ||||||
|  |             if (var2.compareTo(ONE) >= 0 && var2.compareTo(var3) < 0) { | ||||||
|  |                 byte[] var4 = this.digestDoFinal(); | ||||||
|  |                 BigInteger var5 = this.calculateE(var3, var4); | ||||||
|  |                 BigInteger var6 = var1.add(var2).mod(var3); | ||||||
|  |                 if (var6.equals(ZERO)) { | ||||||
|  |                     return false; | ||||||
|  |                 } else { | ||||||
|  |                     ECPoint var7 = ((ECPublicKeyParameters) this.ecKey).getQ(); | ||||||
|  |                     ECPoint var8 = ECAlgorithms | ||||||
|  |                             .sumOfTwoMultiplies(this.ecParams.getG(), var2, var7, var6).normalize(); | ||||||
|  |                     if (var8.isInfinity()) { | ||||||
|  |                         return false; | ||||||
|  |                     } else { | ||||||
|  |                         BigInteger var9 = var5.add(var8.getAffineXCoord().toBigInteger()).mod(var3); | ||||||
|  |                         return var9.equals(var1); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private byte[] digestDoFinal() { | ||||||
|  |         byte[] var1 = new byte[this.digest.getDigestSize()]; | ||||||
|  |         this.digest.doFinal(var1, 0); | ||||||
|  |         this.reset(); | ||||||
|  |         return var1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private byte[] getZ(byte[] var1) { | ||||||
|  |         this.digest.reset(); | ||||||
|  |         this.addUserID(this.digest, var1); | ||||||
|  |         this.addFieldElement(this.digest, this.ecParams.getCurve().getA()); | ||||||
|  |         this.addFieldElement(this.digest, this.ecParams.getCurve().getB()); | ||||||
|  |         this.addFieldElement(this.digest, this.ecParams.getG().getAffineXCoord()); | ||||||
|  |         this.addFieldElement(this.digest, this.ecParams.getG().getAffineYCoord()); | ||||||
|  |         this.addFieldElement(this.digest, this.pubPoint.getAffineXCoord()); | ||||||
|  |         this.addFieldElement(this.digest, this.pubPoint.getAffineYCoord()); | ||||||
|  |         byte[] var2 = new byte[this.digest.getDigestSize()]; | ||||||
|  |         this.digest.doFinal(var2, 0); | ||||||
|  |         return var2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void addUserID(Digest var1, byte[] var2) { | ||||||
|  |         int var3 = var2.length * 8; | ||||||
|  |         var1.update((byte) (var3 >> 8 & 255)); | ||||||
|  |         var1.update((byte) (var3 & 255)); | ||||||
|  |         var1.update(var2, 0, var2.length); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     private void addFieldElement(Digest var1, ECFieldElement var2) { | ||||||
|  |         byte[] var3 = var2.getEncoded(); | ||||||
|  |         var1.update(var3, 0, var3.length); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected ECMultiplier createBasePointMultiplier() { | ||||||
|  |         return new FixedPointCombMultiplier(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     protected BigInteger calculateE(BigInteger var1, byte[] var2) { | ||||||
|  |         return new BigInteger(1, var2); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -44,21 +44,17 @@ 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_A, // a | ||||||
|                     SM2_ECC_P, // q |             SM2_ECC_B); // b | ||||||
|                     SM2_ECC_A, // a |  | ||||||
|                     SM2_ECC_B); // b |  | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 生成ECC密钥对 |      * 生成ECC密钥对 | ||||||
| @ -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,9 +90,8 @@ 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) { | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
| @ -129,7 +123,7 @@ public class SM2Util extends GMBaseUtil { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param pubKey  公钥 |      * @param pubKey 公钥 | ||||||
|      * @param srcData 原文 |      * @param srcData 原文 | ||||||
|      * @return 默认输出C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 |      * @return 默认输出C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||||
|      * @throws InvalidCipherTextException |      * @throws InvalidCipherTextException | ||||||
| @ -141,8 +135,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 pubKey  公钥 |      * @param pubKey 公钥 | ||||||
|      * @param srcData 原文 |      * @param srcData 原文 | ||||||
|      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 |      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||||
|      * @throws InvalidCipherTextException |      * @throws InvalidCipherTextException | ||||||
| @ -155,7 +149,7 @@ public class SM2Util extends GMBaseUtil { | |||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param pubKeyParameters 公钥 |      * @param pubKeyParameters 公钥 | ||||||
|      * @param srcData          原文 |      * @param srcData 原文 | ||||||
|      * @return 默认输出C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 |      * @return 默认输出C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||||
|      * @throws InvalidCipherTextException |      * @throws InvalidCipherTextException | ||||||
|      */ |      */ | ||||||
| @ -165,9 +159,9 @@ public class SM2Util extends GMBaseUtil { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param mode             指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 |      * @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||||
|      * @param pubKeyParameters 公钥 |      * @param pubKeyParameters 公钥 | ||||||
|      * @param srcData          原文 |      * @param srcData 原文 | ||||||
|      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 |      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||||
|      * @throws InvalidCipherTextException |      * @throws InvalidCipherTextException | ||||||
|      */ |      */ | ||||||
| @ -180,8 +174,9 @@ 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 | ||||||
|      */ |      */ | ||||||
| @ -192,9 +187,10 @@ 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 | ||||||
|      */ |      */ | ||||||
| @ -216,15 +213,15 @@ 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 | ||||||
|      */ |      */ | ||||||
| @ -251,8 +249,9 @@ 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 { | ||||||
| @ -261,9 +260,10 @@ 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 | ||||||
|      */ |      */ | ||||||
| @ -275,14 +275,15 @@ 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 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]; | ||||||
| @ -321,8 +322,9 @@ 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 | ||||||
|      */ |      */ | ||||||
| @ -334,9 +336,9 @@ public class SM2Util extends GMBaseUtil { | |||||||
|     /** |     /** | ||||||
|      * DER编码密文 |      * DER编码密文 | ||||||
|      * |      * | ||||||
|      * @param curveLength  曲线长度,SM2的话就是256位。 |      * @param curveLength 曲线长度,SM2的话就是256位。 | ||||||
|      * @param digestLength 摘要长度,如果是SM2的话因为默认使用SM3摘要,SM3摘要长度为32字节。 |      * @param digestLength 摘要长度,如果是SM2的话因为默认使用SM3摘要,SM3摘要长度为32字节。 | ||||||
|      * @param cipher       默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 |      * @param cipher 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||||
|      * @return 默认输出按C1C3C2编码的结果 |      * @return 默认输出按C1C3C2编码的结果 | ||||||
|      * @throws IOException |      * @throws IOException | ||||||
|      */ |      */ | ||||||
| @ -346,15 +348,16 @@ 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); | ||||||
| @ -403,7 +406,7 @@ public class SM2Util extends GMBaseUtil { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param mode      指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 |      * @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||||
|      * @param derCipher 根据mode输入C1C2C3或C1C3C2顺序DER编码后的密文 |      * @param derCipher 根据mode输入C1C2C3或C1C3C2顺序DER编码后的密文 | ||||||
|      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 |      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||||
|      * @throws Exception |      * @throws Exception | ||||||
| @ -450,7 +453,7 @@ public class SM2Util extends GMBaseUtil { | |||||||
|     /** |     /** | ||||||
|      * 签名 |      * 签名 | ||||||
|      * |      * | ||||||
|      * @param priKey  私钥 |      * @param priKey 私钥 | ||||||
|      * @param srcData 原文 |      * @param srcData 原文 | ||||||
|      * @return DER编码后的签名值 |      * @return DER编码后的签名值 | ||||||
|      * @throws CryptoException |      * @throws CryptoException | ||||||
| @ -464,7 +467,7 @@ public class SM2Util extends GMBaseUtil { | |||||||
|      * 签名 不指定withId,则默认withId为字节数组:"1234567812345678".getBytes() |      * 签名 不指定withId,则默认withId为字节数组:"1234567812345678".getBytes() | ||||||
|      * |      * | ||||||
|      * @param priKeyParameters 私钥 |      * @param priKeyParameters 私钥 | ||||||
|      * @param srcData          原文 |      * @param srcData 原文 | ||||||
|      * @return DER编码后的签名值 |      * @return DER编码后的签名值 | ||||||
|      * @throws CryptoException |      * @throws CryptoException | ||||||
|      */ |      */ | ||||||
| @ -476,8 +479,8 @@ public class SM2Util extends GMBaseUtil { | |||||||
|     /** |     /** | ||||||
|      * 私钥签名 |      * 私钥签名 | ||||||
|      * |      * | ||||||
|      * @param priKey  私钥 |      * @param priKey 私钥 | ||||||
|      * @param withId  可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() |      * @param withId 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||||
|      * @param srcData 原文 |      * @param srcData 原文 | ||||||
|      * @return DER编码后的签名值 |      * @return DER编码后的签名值 | ||||||
|      * @throws CryptoException |      * @throws CryptoException | ||||||
| @ -492,14 +495,13 @@ public class SM2Util extends GMBaseUtil { | |||||||
|      * 签名 |      * 签名 | ||||||
|      * |      * | ||||||
|      * @param priKeyParameters 私钥 |      * @param priKeyParameters 私钥 | ||||||
|      * @param withId           可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() |      * @param withId 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||||
|      * @param srcData          源数据 |      * @param srcData 源数据 | ||||||
|      * @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()); | ||||||
| @ -576,22 +578,22 @@ public class SM2Util extends GMBaseUtil { | |||||||
|      * 验签 不指定withId,则默认withId为字节数组:"1234567812345678".getBytes() |      * 验签 不指定withId,则默认withId为字节数组:"1234567812345678".getBytes() | ||||||
|      * |      * | ||||||
|      * @param pubKeyParameters 公钥 |      * @param pubKeyParameters 公钥 | ||||||
|      * @param srcData          原文 |      * @param srcData 原文 | ||||||
|      * @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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 验签 |      * 验签 | ||||||
|      * |      * | ||||||
|      * @param pubKey  公钥 |      * @param pubKey 公钥 | ||||||
|      * @param withId  可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() |      * @param withId 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||||
|      * @param srcData 原文 |      * @param srcData 原文 | ||||||
|      * @param sign    DER编码的签名值 |      * @param sign DER编码的签名值 | ||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     public static boolean verify(BCECPublicKey pubKey, byte[] withId, byte[] srcData, byte[] sign) { |     public static boolean verify(BCECPublicKey pubKey, byte[] withId, byte[] srcData, byte[] sign) { | ||||||
| @ -603,13 +605,13 @@ public class SM2Util extends GMBaseUtil { | |||||||
|      * 验签 |      * 验签 | ||||||
|      * |      * | ||||||
|      * @param pubKeyParameters 公钥 |      * @param pubKeyParameters 公钥 | ||||||
|      * @param withId           可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() |      * @param withId 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||||
|      * @param srcData          原文 |      * @param srcData 原文 | ||||||
|      * @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) { | ||||||
| @ -647,13 +649,12 @@ public class SM2Util extends GMBaseUtil { | |||||||
|             byte[] sigByte = ByteUtils.fromHexString(signature); |             byte[] sigByte = ByteUtils.fromHexString(signature); | ||||||
|             // TODO 是否需要der编码? |             // TODO 是否需要der编码? | ||||||
|             // try { |             // try { | ||||||
|             //   sigByte = SM2Util.encodeSM2SignToDER(sigByte); |             // sigByte = SM2Util.encodeSM2SignToDER(sigByte); | ||||||
|             // } 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) { | ||||||
|  | |||||||
| @ -41,7 +41,7 @@ public class SM3Util extends GMBaseUtil { | |||||||
|     /** |     /** | ||||||
|      * 计算SM3 Mac值 |      * 计算SM3 Mac值 | ||||||
|      * |      * | ||||||
|      * @param key     key值,可以是任意长度的字节数组 |      * @param key key值,可以是任意长度的字节数组 | ||||||
|      * @param srcData 原文 |      * @param srcData 原文 | ||||||
|      * @return Mac值,对于HMac-SM3来说是32字节 |      * @return Mac值,对于HMac-SM3来说是32字节 | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -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)); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ public class RandomSNAllocator implements CertSNAllocator { | |||||||
| 
 | 
 | ||||||
|     private static int[] AND_MASKS = new int[] {0xFF, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F}; |     private static int[] AND_MASKS = new int[] {0xFF, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F}; | ||||||
| 
 | 
 | ||||||
|     private static int[]  OR_MASKS = new int[] {0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40}; |     private static int[] OR_MASKS = new int[] {0x80, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40}; | ||||||
| 
 | 
 | ||||||
|     private final SecureRandom random; |     private final SecureRandom random; | ||||||
| 
 | 
 | ||||||
| @ -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(); | ||||||
|  | |||||||
| @ -33,17 +33,17 @@ public class SM2CertUtil { | |||||||
|         ECPublicKey pubKey = (ECPublicKey) sm2Cert.getPublicKey(); |         ECPublicKey pubKey = (ECPublicKey) sm2Cert.getPublicKey(); | ||||||
|         ECPoint q = pubKey.getQ(); |         ECPoint q = pubKey.getQ(); | ||||||
|         ECParameterSpec parameterSpec = new ECParameterSpec(SM2Util.CURVE, SM2Util.G_POINT, |         ECParameterSpec parameterSpec = new ECParameterSpec(SM2Util.CURVE, SM2Util.G_POINT, | ||||||
|             SM2Util.SM2_ECC_N, SM2Util.SM2_ECC_H); |                 SM2Util.SM2_ECC_N, SM2Util.SM2_ECC_H); | ||||||
|         ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(q, parameterSpec); |         ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(q, parameterSpec); | ||||||
|         return new BCECPublicKey(pubKey.getAlgorithm(), pubKeySpec, |         return new BCECPublicKey(pubKey.getAlgorithm(), pubKeySpec, | ||||||
|             BouncyCastleProvider.CONFIGURATION); |                 BouncyCastleProvider.CONFIGURATION); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * 校验证书 |      * 校验证书 | ||||||
|      * |      * | ||||||
|      * @param issuerPubKey 从颁发者CA证书中提取出来的公钥 |      * @param issuerPubKey 从颁发者CA证书中提取出来的公钥 | ||||||
|      * @param cert         待校验的证书 |      * @param cert 待校验的证书 | ||||||
|      * @return |      * @return | ||||||
|      */ |      */ | ||||||
|     public static boolean verifyCertificate(BCECPublicKey issuerPubKey, X509Certificate cert) { |     public static boolean verifyCertificate(BCECPublicKey issuerPubKey, X509Certificate cert) { | ||||||
| @ -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; | ||||||
|  | |||||||
| @ -21,41 +21,41 @@ public class SM2PfxMaker { | |||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param privKey 用户私钥 |      * @param privKey 用户私钥 | ||||||
|      * @param pubKey  用户公钥 |      * @param pubKey 用户公钥 | ||||||
|      * @param chain   X509证书数组,切记这里固定了必须是3个元素的数组,且第一个必须是叶子证书、第二个为中级CA证书、第三个为根CA证书 |      * @param chain X509证书数组,切记这里固定了必须是3个元素的数组,且第一个必须是叶子证书、第二个为中级CA证书、第三个为根CA证书 | ||||||
|      * @param passwd  口令 |      * @param passwd 口令 | ||||||
|      * @return |      * @return | ||||||
|      * @throws NoSuchAlgorithmException |      * @throws NoSuchAlgorithmException | ||||||
|      * @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]); | ||||||
|         taCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, |         taCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||||
|             new DERBMPString("Primary Certificate")); |                 new DERBMPString("Primary Certificate")); | ||||||
| 
 | 
 | ||||||
|         PKCS12SafeBagBuilder caCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[1]); |         PKCS12SafeBagBuilder caCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[1]); | ||||||
|         caCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, |         caCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||||
|             new DERBMPString("Intermediate Certificate")); |                 new DERBMPString("Intermediate Certificate")); | ||||||
| 
 | 
 | ||||||
|         PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[0]); |         PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[0]); | ||||||
|         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, |         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||||
|             new DERBMPString("User Key")); |                 new DERBMPString("User Key")); | ||||||
|         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, |         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, | ||||||
|             extUtils.createSubjectKeyIdentifier(pubKey)); |                 extUtils.createSubjectKeyIdentifier(pubKey)); | ||||||
| 
 | 
 | ||||||
|         char[] passwdChars = passwd.toCharArray(); |         char[] passwdChars = passwd.toCharArray(); | ||||||
|         PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, |         PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, | ||||||
|             new BcPKCS12PBEOutputEncryptorBuilder( |                 new BcPKCS12PBEOutputEncryptorBuilder( | ||||||
|                 PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, |                         PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, | ||||||
|                 new CBCBlockCipher(new DESedeEngine())).build(passwdChars)); |                         new CBCBlockCipher(new DESedeEngine())).build(passwdChars)); | ||||||
|         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, |         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||||
|             new DERBMPString("User Key")); |                 new DERBMPString("User Key")); | ||||||
|         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, |         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, | ||||||
|             extUtils.createSubjectKeyIdentifier(pubKey)); |                 extUtils.createSubjectKeyIdentifier(pubKey)); | ||||||
| 
 | 
 | ||||||
|         PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder(); |         PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder(); | ||||||
|         PKCS12SafeBag[] certs = new PKCS12SafeBag[3]; |         PKCS12SafeBag[] certs = new PKCS12SafeBag[3]; | ||||||
| @ -64,49 +64,47 @@ 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); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param privKey 用户私钥 |      * @param privKey 用户私钥 | ||||||
|      * @param pubKey  用户公钥 |      * @param pubKey 用户公钥 | ||||||
|      * @param cert    X509证书 |      * @param cert X509证书 | ||||||
|      * @param passwd  口令 |      * @param passwd 口令 | ||||||
|      * @return |      * @return | ||||||
|      * @throws NoSuchAlgorithmException |      * @throws NoSuchAlgorithmException | ||||||
|      * @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); | ||||||
|         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, |         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||||
|             new DERBMPString("User Key")); |                 new DERBMPString("User Key")); | ||||||
|         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, |         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, | ||||||
|             extUtils.createSubjectKeyIdentifier(pubKey)); |                 extUtils.createSubjectKeyIdentifier(pubKey)); | ||||||
| 
 | 
 | ||||||
|         char[] passwdChars = passwd.toCharArray(); |         char[] passwdChars = passwd.toCharArray(); | ||||||
|         PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, |         PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, | ||||||
|             new BcPKCS12PBEOutputEncryptorBuilder( |                 new BcPKCS12PBEOutputEncryptorBuilder( | ||||||
|                 PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, |                         PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, | ||||||
|                 new CBCBlockCipher(new DESedeEngine())).build(passwdChars)); |                         new CBCBlockCipher(new DESedeEngine())).build(passwdChars)); | ||||||
|         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, |         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||||
|             new DERBMPString("User Key")); |                 new DERBMPString("User Key")); | ||||||
|         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, |         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, | ||||||
|             extUtils.createSubjectKeyIdentifier(pubKey)); |                 extUtils.createSubjectKeyIdentifier(pubKey)); | ||||||
| 
 | 
 | ||||||
|         PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder(); |         PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder(); | ||||||
|         PKCS12SafeBag[] certs = new PKCS12SafeBag[1]; |         PKCS12SafeBag[] certs = new PKCS12SafeBag[1]; | ||||||
|         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,9 +12,8 @@ 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 | ||||||
|      * @throws KeyStoreException |      * @throws KeyStoreException | ||||||
| @ -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); | ||||||
| @ -34,16 +33,16 @@ public class SM2Pkcs12Maker { | |||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param privKey 用户私钥 |      * @param privKey 用户私钥 | ||||||
|      * @param cert    X509证书 |      * @param cert X509证书 | ||||||
|      * @param passwd  口令 |      * @param passwd 口令 | ||||||
|      * @return the PKCS12 keystore |      * @return the PKCS12 keystore | ||||||
|      * @throws NoSuchAlgorithmException |      * @throws NoSuchAlgorithmException | ||||||
|      * @throws IOException |      * @throws IOException | ||||||
|      * @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,10 +77,11 @@ 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 | ||||||
|             return null; |             return null; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -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,13 +27,13 @@ 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( | ||||||
|             new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ID_SM2_PUBKEY_PARAM), |                 new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ID_SM2_PUBKEY_PARAM), | ||||||
|             p.getOctets()); |                 p.getOctets()); | ||||||
| 
 | 
 | ||||||
|         return KeyUtil.getEncodedSubjectPublicKeyInfo(info); |         return KeyUtil.getEncodedSubjectPublicKeyInfo(info); | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -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,16 +39,14 @@ public class SM2X509CertMaker { | |||||||
|     private KeyPair issuerKeyPair; |     private KeyPair issuerKeyPair; | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param issuerKeyPair 证书颁发者的密钥对。 |      * @param issuerKeyPair 证书颁发者的密钥对。 其实一般的CA的私钥都是要严格保护的。 一般CA的私钥都会放在加密卡/加密机里,证书的签名由加密卡/加密机完成。 | ||||||
|      *                      其实一般的CA的私钥都是要严格保护的。 |      *        这里仅是为了演示BC库签发证书的用法,所以暂时不作太多要求。 | ||||||
|      *                      一般CA的私钥都会放在加密卡/加密机里,证书的签名由加密卡/加密机完成。 |      * @param certExpire 证书有效时间,单位毫秒 | ||||||
|      *                      这里仅是为了演示BC库签发证书的用法,所以暂时不作太多要求。 |      * @param issuer 证书颁发者信息 | ||||||
|      * @param certExpire    证书有效时间,单位毫秒 |      * @param snAllocator 维护/分配证书序列号的实例,证书序列号应该递增且不重复 | ||||||
|      * @param issuer        证书颁发者信息 |  | ||||||
|      * @param snAllocator   维护/分配证书序列号的实例,证书序列号应该递增且不重复 |  | ||||||
|      */ |      */ | ||||||
|     public SM2X509CertMaker(KeyPair issuerKeyPair, long certExpire, X500Name issuer, |     public SM2X509CertMaker(KeyPair issuerKeyPair, long certExpire, X500Name issuer, | ||||||
|                             CertSNAllocator snAllocator) { |             CertSNAllocator snAllocator) { | ||||||
|         this.issuerKeyPair = issuerKeyPair; |         this.issuerKeyPair = issuerKeyPair; | ||||||
|         this.certExpire = certExpire; |         this.certExpire = certExpire; | ||||||
|         this.issuerDN = issuer; |         this.issuerDN = 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,10 +84,9 @@ 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,28 +97,26 @@ 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); | ||||||
|         return makeCertificate(CertLevel.SubCA, null, csr, usage, extendedKeyUsages); |         return makeCertificate(CertLevel.SubCA, null, csr, usage, extendedKeyUsages); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /** |     /** | ||||||
|      * @param isCA     是否是颁发给CA的证书 |      * @param isCA 是否是颁发给CA的证书 | ||||||
|      * @param keyUsage 证书用途 |      * @param keyUsage 证书用途 | ||||||
|      * @param csr      CSR |      * @param csr CSR | ||||||
|      * @return |      * @return | ||||||
|      * @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( | ||||||
|                   "keyusage keyCertSign is not allowed in EndEntity Certificate"); |                         "keyusage keyCertSign is not allowed in EndEntity Certificate"); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -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,13 +166,14 @@ 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: | ||||||
|                 if (issuerDN.equals(subject)) { |                 if (issuerDN.equals(subject)) { | ||||||
|                     throw new IllegalArgumentException( |                     throw new IllegalArgumentException( | ||||||
|                         "subject MUST not equals issuer for certLevel " + certLevel); |                             "subject MUST not equals issuer for certLevel " + certLevel); | ||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
|             default: |             default: | ||||||
| @ -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,20 +232,21 @@ 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); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (!subjectAltNames.isEmpty()) { |         if (!subjectAltNames.isEmpty()) { | ||||||
|             v3CertGen.addExtension(Extension.subjectAlternativeName, false, |             v3CertGen.addExtension(Extension.subjectAlternativeName, false, | ||||||
|                 new GeneralNames(subjectAltNames.toArray(new GeneralName[0]))); |                     new GeneralNames(subjectAltNames.toArray(new GeneralName[0]))); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         JcaContentSignerBuilder contentSignerBuilder = makeContentSignerBuilder(issPub); |         JcaContentSignerBuilder contentSignerBuilder = makeContentSignerBuilder(issPub); | ||||||
|         X509Certificate cert = new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME) |         X509Certificate cert = | ||||||
|             .getCertificate(v3CertGen.build(contentSignerBuilder.build(issPriv))); |                 new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME) | ||||||
|  |                         .getCertificate(v3CertGen.build(contentSignerBuilder.build(issPriv))); | ||||||
|         cert.verify(issPub); |         cert.verify(issPub); | ||||||
| 
 | 
 | ||||||
|         return cert; |         return cert; | ||||||
| @ -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; | ||||||
|         } |         } | ||||||
|  | |||||||
							
								
								
									
										30
									
								
								src/main/java/org/paillier/PaillierCipher.java
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										30
									
								
								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,11 +49,8 @@ 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 |                 .multiply(rsaPriKey.getPrimeQ().subtract(BigInteger.ONE)); | ||||||
|                         .getPrimeP() |  | ||||||
|                         .subtract(BigInteger.ONE) |  | ||||||
|                         .multiply(rsaPriKey.getPrimeQ().subtract(BigInteger.ONE)); |  | ||||||
| 
 | 
 | ||||||
|         int nLen = CommonUtils.byte2ToUnsignedShort(ciphertext); |         int nLen = CommonUtils.byte2ToUnsignedShort(ciphertext); | ||||||
|         byte[] nBytes = new byte[nLen]; |         byte[] nBytes = new byte[nLen]; | ||||||
| @ -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,10 +78,8 @@ 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(ciphertext2))); | ||||||
|                         CommonUtils.hexStringToBytes(ciphertext1), |  | ||||||
|                         CommonUtils.hexStringToBytes(ciphertext2))); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public static byte[] ciphertextAdd(byte[] ciphertext1, byte[] ciphertext2) { |     public static byte[] ciphertextAdd(byte[] ciphertext1, byte[] 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; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										60
									
								
								src/test/java/org/paillier/PaillierTest.java
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										60
									
								
								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; | ||||||
| @ -18,7 +16,7 @@ public class PaillierTest { | |||||||
|         KeyPair keypair = PaillierKeyPair.generateGoodKeyPair(); |         KeyPair keypair = PaillierKeyPair.generateGoodKeyPair(); | ||||||
|         RSAPublicKey pubKey = (RSAPublicKey) keypair.getPublic(); |         RSAPublicKey pubKey = (RSAPublicKey) keypair.getPublic(); | ||||||
|         RSAPrivateCrtKey priKey = (RSAPrivateCrtKey) keypair.getPrivate(); |         RSAPrivateCrtKey priKey = (RSAPrivateCrtKey) keypair.getPrivate(); | ||||||
|          System.out.println("e:" + priKey.getPublicExponent().intValue()); |         System.out.println("e:" + priKey.getPublicExponent().intValue()); | ||||||
| 
 | 
 | ||||||
|         String publicKeyStr = PaillierKeyPair.publicKeyToPem(pubKey); |         String publicKeyStr = PaillierKeyPair.publicKeyToPem(pubKey); | ||||||
|         String privateKeyStr = PaillierKeyPair.privateKeyToPem(priKey); |         String privateKeyStr = PaillierKeyPair.privateKeyToPem(priKey); | ||||||
| @ -62,35 +60,33 @@ 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" |                 + "TO7B09AcDNccdDyI+gXP4LEsIoh9HR1p41cq1RKe5c9khLryc5zQqf6NWlw4aWr9\n" | ||||||
|                         + "TO7B09AcDNccdDyI+gXP4LEsIoh9HR1p41cq1RKe5c9khLryc5zQqf6NWlw4aWr9\n" |                 + "AI5w4m7zhsTiDH1R9qLSJugOltY+9hLF7E9LexMLwXoQUYyi0WGxRe0h03+EQszv\n" | ||||||
|                         + "AI5w4m7zhsTiDH1R9qLSJugOltY+9hLF7E9LexMLwXoQUYyi0WGxRe0h03+EQszv\n" |                 + "4gQA4paJPAnk8k6VrUyTlBdeoYneInxZ0FEtFffk/rqVt4B80jjVRTbleSmDNvb7\n" | ||||||
|                         + "4gQA4paJPAnk8k6VrUyTlBdeoYneInxZ0FEtFffk/rqVt4B80jjVRTbleSmDNvb7\n" |                 + "KFp+KHSrAgMBAAECggEAG0jM2jQ3ul0tCLccD2+c7Y4cMaB5AixWbuZzkcvE1mUM\n" | ||||||
|                         + "KFp+KHSrAgMBAAECggEAG0jM2jQ3ul0tCLccD2+c7Y4cMaB5AixWbuZzkcvE1mUM\n" |                 + "xNh52Io2THDnIPDOLI9GCCoJiwokzd10vVcNAa30RHR2co327+1/gmpXStYb/BXg\n" | ||||||
|                         + "xNh52Io2THDnIPDOLI9GCCoJiwokzd10vVcNAa30RHR2co327+1/gmpXStYb/BXg\n" |                 + "/ynDtjMV8STeruf05xVa/IUyANLqIafbC4XFLqYk1tKnU8O1hfHwBbwFZlkao5QH\n" | ||||||
|                         + "/ynDtjMV8STeruf05xVa/IUyANLqIafbC4XFLqYk1tKnU8O1hfHwBbwFZlkao5QH\n" |                 + "IN9CyDIsyyv30JbHz47HJePZkTm/2iOq4ru+pKYFHeDz4EIEJRGl8HD7wtpo3F5E\n" | ||||||
|                         + "IN9CyDIsyyv30JbHz47HJePZkTm/2iOq4ru+pKYFHeDz4EIEJRGl8HD7wtpo3F5E\n" |                 + "mxe9uI5GMCdbswGnmw1a0u/VrSXpxwVyQMGHP6KWZ0dIunFW0Sh4DEdf9/tygtwx\n" | ||||||
|                         + "mxe9uI5GMCdbswGnmw1a0u/VrSXpxwVyQMGHP6KWZ0dIunFW0Sh4DEdf9/tygtwx\n" |                 + "nJ+/RYGqTKLv59+OkJGH/e6J6BV9rKYfjTiRC+hAAQKBgQD/1dW9WSXnquVGdJkq\n" | ||||||
|                         + "nJ+/RYGqTKLv59+OkJGH/e6J6BV9rKYfjTiRC+hAAQKBgQD/1dW9WSXnquVGdJkq\n" |                 + "QnohnMp/EkaXA3e3RiS9Bx9hhNwfdijqx3zyV1LnHGhuEaCXSCoy6zIOLQxOkkA8\n" | ||||||
|                         + "QnohnMp/EkaXA3e3RiS9Bx9hhNwfdijqx3zyV1LnHGhuEaCXSCoy6zIOLQxOkkA8\n" |                 + "rLCzpN/hp3c8pQUwYlQodZ+G/0272jCsD2vmdOuRP2WuFA9hqGgFvUbXkXh4mcEB\n" | ||||||
|                         + "rLCzpN/hp3c8pQUwYlQodZ+G/0272jCsD2vmdOuRP2WuFA9hqGgFvUbXkXh4mcEB\n" |                 + "xKJY/jAddZvmnvs/dcLt6oJMqwKBgQC1nd18hcjQmIRARRUGs1ZU75yTaLKp+lXf\n" | ||||||
|                         + "xKJY/jAddZvmnvs/dcLt6oJMqwKBgQC1nd18hcjQmIRARRUGs1ZU75yTaLKp+lXf\n" |                 + "M7lg8RKE9sWf4ZoT3Snj+pimUOqliE10LiHruawa137q/UC+iI0/I4H9AUhv2mAw\n" | ||||||
|                         + "M7lg8RKE9sWf4ZoT3Snj+pimUOqliE10LiHruawa137q/UC+iI0/I4H9AUhv2mAw\n" |                 + "m5drd+G4s6uTiCf7OQxBTmGHEvv5xH7gQih6sjOJI+N57xanC1XMGxijMOSy/D+O\n" | ||||||
|                         + "m5drd+G4s6uTiCf7OQxBTmGHEvv5xH7gQih6sjOJI+N57xanC1XMGxijMOSy/D+O\n" |                 + "sLxB8yJ4AQKBgQDYYX3kJnB+3vYIfznEmnE92KUUkNqPg2lP483S6yFJk9ux6Hh3\n" | ||||||
|                         + "sLxB8yJ4AQKBgQDYYX3kJnB+3vYIfznEmnE92KUUkNqPg2lP483S6yFJk9ux6Hh3\n" |                 + "Cr7NIbqGqmpRHiubiHfYlUDC6KsOEXivWMgjSQHqk3+wFUqsP546kjGZNnoCtmqQ\n" | ||||||
|                         + "Cr7NIbqGqmpRHiubiHfYlUDC6KsOEXivWMgjSQHqk3+wFUqsP546kjGZNnoCtmqQ\n" |                 + "PILgameLc/mGIIVZ7dv9brdqQCmKp1CtNCiz6Fm9sOlpR3HtnKaAH+aQ/QKBgFVW\n" | ||||||
|                         + "PILgameLc/mGIIVZ7dv9brdqQCmKp1CtNCiz6Fm9sOlpR3HtnKaAH+aQ/QKBgFVW\n" |                 + "37tidfEmqYY1r+KdJGT2zqEpokJi4jTmbiZSQPx/pG8zKB5LXyLEHzSPcyLjQFnm\n" | ||||||
|                         + "37tidfEmqYY1r+KdJGT2zqEpokJi4jTmbiZSQPx/pG8zKB5LXyLEHzSPcyLjQFnm\n" |                 + "T4Qfk/Js7jNnWyPssEpJ2gvTrYD5oRdWFTmndEZBDs9dPEQ9Ezggp40763D61w9z\n" | ||||||
|                         + "T4Qfk/Js7jNnWyPssEpJ2gvTrYD5oRdWFTmndEZBDs9dPEQ9Ezggp40763D61w9z\n" |                 + "pue4kqTPW1Vxdjh6CA/Hb7VHBT/hbdAT1fI7WCgBAoGAZq1rFESL3roi8DtOWl51\n" | ||||||
|                         + "pue4kqTPW1Vxdjh6CA/Hb7VHBT/hbdAT1fI7WCgBAoGAZq1rFESL3roi8DtOWl51\n" |                 + "nduNO20Yloe6tlhUAKo63krRHKBeKTyLXycpZHcq6UEfys3dixFfu0lN6002lUku\n" | ||||||
|                         + "nduNO20Yloe6tlhUAKo63krRHKBeKTyLXycpZHcq6UEfys3dixFfu0lN6002lUku\n" |                 + "MTbmNOJWhOCa2xuZY0CeINKFnKBnbiauBpo6x+2J0PoWFn8wd1tzFJPbodk8Km1f\n" | ||||||
|                         + "MTbmNOJWhOCa2xuZY0CeINKFnKBnbiauBpo6x+2J0PoWFn8wd1tzFJPbodk8Km1f\n" |                 + "qySov+6mrQxHojQYBu9/yYQ=\n" + "-----END PRIVATE KEY-----"; | ||||||
|                         + "qySov+6mrQxHojQYBu9/yYQ=\n" |  | ||||||
|                         + "-----END PRIVATE KEY-----"; |  | ||||||
| 
 | 
 | ||||||
|         String cipher = |         String cipher = | ||||||
|                 "0100B57FF39AFFF23E48534DBFE3E61C6275BCB1850EEE80D08415F43717FE17F64762455BF38DC5F8E5AED021E1D5BB8AD330200EAEEB85252A29A5E14B95053F5C6B8C2FED1F3B0C5AA1C6ABA1F8E6CCCE8DB1E9001A5E7BCBE56326BBCFBF68B83A35CD3A057B491EC8B04CEEC1D3D01C0CD71C743C88FA05CFE0B12C22887D1D1D69E3572AD5129EE5CF6484BAF2739CD0A9FE8D5A5C38696AFD008E70E26EF386C4E20C7D51F6A2D226E80E96D63EF612C5EC4F4B7B130BC17A10518CA2D161B145ED21D37F8442CCEFE20400E296893C09E4F24E95AD4C9394175EA189DE227C59D0512D15F7E4FEBA95B7807CD238D54536E579298336F6FB285A7E2874AB6914BF4FF089BFD98EC18D9E8B3D7FB2F5CFC20715C62D34F08E36D84F2CDABA2D1A1798C95161B7831167ED27E8894F1EB25D4E74DF382BF276D9ACBEADB56795F3DF8A4E6CE9DF7B6CFEFD5C66F0BC45D24CCC8E8095A7BF5CE69FEC5579B874A4C9B7C8F13126EC59D7C6DF0404816F638C7D4A84FE038E6F00B5667AC88E4307990E4C06B3864D86B7349275B20A3FB50FBA64706F214CC642219DCEF4453C30B89790F6FB1566A5D557AD7EC5890CA50E80111319F9742943FBD675D18753E5ABD21941832A11332ED902C334309E3770512AC042E1556C3F0ECCFC056C66D7362BA4E7896EA0807412817C68D7B5434AFA0D95A12B950573994F081F996545B871E485C392288E2D61C3B0CBB9FC4E68C1C558A598B03BACFF27967BE8AEA8F1322EC3E0957A3ED84810164A59BDEE2D1514EA68228CB96B59D8BA1E9234A24D57E5F8D7E55724EF0AE9D83F6E2A84B9A1E47B59091201B1B65542BBBB5A988CBBD5395335C4DF821ACEF289D20444B74CABC406A7C4F810EFF85838994DBDD38EDF74D4821153A5128AB98C15409C73891415B194803B3ABF761CEE57D1F58813A7125260E58864970CA2650E0D46C239ED92FCC3491C5FA372838B475D14E4946FCC3C421A76C434C5310D1A17A744551CFB5F99547BB216AD7C1ADA5C27CA64B34C29152D29B0A4B90B0C72A7A18BD19CF278B6F39186A39F91FB4D"; |                 "0100B57FF39AFFF23E48534DBFE3E61C6275BCB1850EEE80D08415F43717FE17F64762455BF38DC5F8E5AED021E1D5BB8AD330200EAEEB85252A29A5E14B95053F5C6B8C2FED1F3B0C5AA1C6ABA1F8E6CCCE8DB1E9001A5E7BCBE56326BBCFBF68B83A35CD3A057B491EC8B04CEEC1D3D01C0CD71C743C88FA05CFE0B12C22887D1D1D69E3572AD5129EE5CF6484BAF2739CD0A9FE8D5A5C38696AFD008E70E26EF386C4E20C7D51F6A2D226E80E96D63EF612C5EC4F4B7B130BC17A10518CA2D161B145ED21D37F8442CCEFE20400E296893C09E4F24E95AD4C9394175EA189DE227C59D0512D15F7E4FEBA95B7807CD238D54536E579298336F6FB285A7E2874AB6914BF4FF089BFD98EC18D9E8B3D7FB2F5CFC20715C62D34F08E36D84F2CDABA2D1A1798C95161B7831167ED27E8894F1EB25D4E74DF382BF276D9ACBEADB56795F3DF8A4E6CE9DF7B6CFEFD5C66F0BC45D24CCC8E8095A7BF5CE69FEC5579B874A4C9B7C8F13126EC59D7C6DF0404816F638C7D4A84FE038E6F00B5667AC88E4307990E4C06B3864D86B7349275B20A3FB50FBA64706F214CC642219DCEF4453C30B89790F6FB1566A5D557AD7EC5890CA50E80111319F9742943FBD675D18753E5ABD21941832A11332ED902C334309E3770512AC042E1556C3F0ECCFC056C66D7362BA4E7896EA0807412817C68D7B5434AFA0D95A12B950573994F081F996545B871E485C392288E2D61C3B0CBB9FC4E68C1C558A598B03BACFF27967BE8AEA8F1322EC3E0957A3ED84810164A59BDEE2D1514EA68228CB96B59D8BA1E9234A24D57E5F8D7E55724EF0AE9D83F6E2A84B9A1E47B59091201B1B65542BBBB5A988CBBD5395335C4DF821ACEF289D20444B74CABC406A7C4F810EFF85838994DBDD38EDF74D4821153A5128AB98C15409C73891415B194803B3ABF761CEE57D1F58813A7125260E58864970CA2650E0D46C239ED92FCC3491C5FA372838B475D14E4946FCC3C421A76C434C5310D1A17A744551CFB5F99547BB216AD7C1ADA5C27CA64B34C29152D29B0A4B90B0C72A7A18BD19CF278B6F39186A39F91FB4D"; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user