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 'signing' | ||||
| } | ||||
| 
 | ||||
| apply from: '../spotless.gradle' | ||||
| 
 | ||||
| group 'org.bdware.bdcontract' | ||||
| version '0.2.0' | ||||
| sourceCompatibility = 1.8 | ||||
|  | ||||
| @ -57,15 +57,12 @@ public class BCECUtil { | ||||
|     } | ||||
| 
 | ||||
|     public static KeyPair generateKeyPair(ECDomainParameters domainParameters, SecureRandom random) | ||||
|             throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException { | ||||
|             throws NoSuchProviderException, NoSuchAlgorithmException, | ||||
|             InvalidAlgorithmParameterException { | ||||
|         KeyPairGenerator kpg = | ||||
|                 KeyPairGenerator.getInstance(ALGO_NAME_EC, BouncyCastleProvider.PROVIDER_NAME); | ||||
|         ECParameterSpec parameterSpec = | ||||
|                 new ECParameterSpec( | ||||
|                         domainParameters.getCurve(), | ||||
|                         domainParameters.getG(), | ||||
|                         domainParameters.getN(), | ||||
|                         domainParameters.getH()); | ||||
|         ECParameterSpec parameterSpec = new ECParameterSpec(domainParameters.getCurve(), | ||||
|                 domainParameters.getG(), domainParameters.getN(), domainParameters.getH()); | ||||
|         kpg.initialize(parameterSpec, (null == random ? new SecureRandom() : random)); | ||||
|         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} | ||||
|      * @return | ||||
|      */ | ||||
|     public static ECPrivateKeyParameters createECPrivateKeyParameters( | ||||
|             String dHex, ECDomainParameters domainParameters) { | ||||
|     public static ECPrivateKeyParameters createECPrivateKeyParameters(String dHex, | ||||
|             ECDomainParameters 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} | ||||
|      * @return | ||||
|      */ | ||||
|     public static ECPrivateKeyParameters createECPrivateKeyParameters( | ||||
|             byte[] dBytes, ECDomainParameters domainParameters) { | ||||
|     public static ECPrivateKeyParameters createECPrivateKeyParameters(byte[] dBytes, | ||||
|             ECDomainParameters domainParameters) { | ||||
|         return createECPrivateKeyParameters(new BigInteger(1, dBytes), domainParameters); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param d                大数形式的私钥d值 | ||||
|      * @param d 大数形式的私钥d值 | ||||
|      * @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS} | ||||
|      * @return | ||||
|      */ | ||||
|     public static ECPrivateKeyParameters createECPrivateKeyParameters( | ||||
|             BigInteger d, ECDomainParameters domainParameters) { | ||||
|     public static ECPrivateKeyParameters createECPrivateKeyParameters(BigInteger d, | ||||
|             ECDomainParameters domainParameters) { | ||||
|         return new ECPrivateKeyParameters(d, domainParameters); | ||||
|     } | ||||
| 
 | ||||
| @ -128,46 +125,48 @@ public class BCECUtil { | ||||
|      * @param priKey ECC私钥参数对象 | ||||
|      * @return | ||||
|      */ | ||||
|     public static ECPublicKeyParameters buildECPublicKeyByPrivateKey(ECPrivateKeyParameters priKey) { | ||||
|     public static ECPublicKeyParameters buildECPublicKeyByPrivateKey( | ||||
|             ECPrivateKeyParameters priKey) { | ||||
|         ECDomainParameters domainParameters = priKey.getParameters(); | ||||
|         ECPoint q = new FixedPointCombMultiplier().multiply(domainParameters.getG(), priKey.getD()); | ||||
|         return new ECPublicKeyParameters(q, domainParameters); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param x                大数形式的公钥x分量 | ||||
|      * @param y                大数形式的公钥y分量 | ||||
|      * @param curve            EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||
|      * @param x 大数形式的公钥x分量 | ||||
|      * @param y 大数形式的公钥y分量 | ||||
|      * @param curve EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||
|      * @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS} | ||||
|      * @return | ||||
|      */ | ||||
|     public static ECPublicKeyParameters createECPublicKeyParameters( | ||||
|             BigInteger x, BigInteger y, ECCurve curve, ECDomainParameters domainParameters) { | ||||
|         return createECPublicKeyParameters(x.toByteArray(), y.toByteArray(), curve, domainParameters); | ||||
|     public static ECPublicKeyParameters createECPublicKeyParameters(BigInteger x, BigInteger y, | ||||
|             ECCurve curve, ECDomainParameters domainParameters) { | ||||
|         return createECPublicKeyParameters(x.toByteArray(), y.toByteArray(), curve, | ||||
|                 domainParameters); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param xHex             十六进制形式的公钥x分量,如果是SM2算法,Hex字符串长度应该是64(即32字节) | ||||
|      * @param yHex             十六进制形式的公钥y分量,如果是SM2算法,Hex字符串长度应该是64(即32字节) | ||||
|      * @param curve            EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||
|      * @param xHex 十六进制形式的公钥x分量,如果是SM2算法,Hex字符串长度应该是64(即32字节) | ||||
|      * @param yHex 十六进制形式的公钥y分量,如果是SM2算法,Hex字符串长度应该是64(即32字节) | ||||
|      * @param curve EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||
|      * @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS} | ||||
|      * @return | ||||
|      */ | ||||
|     public static ECPublicKeyParameters createECPublicKeyParameters( | ||||
|             String xHex, String yHex, ECCurve curve, ECDomainParameters domainParameters) { | ||||
|         return createECPublicKeyParameters( | ||||
|                 ByteUtils.fromHexString(xHex), ByteUtils.fromHexString(yHex), curve, domainParameters); | ||||
|     public static ECPublicKeyParameters createECPublicKeyParameters(String xHex, String yHex, | ||||
|             ECCurve curve, ECDomainParameters domainParameters) { | ||||
|         return createECPublicKeyParameters(ByteUtils.fromHexString(xHex), | ||||
|                 ByteUtils.fromHexString(yHex), curve, domainParameters); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param xBytes           十六进制形式的公钥x分量,如果是SM2算法,应该是32字节 | ||||
|      * @param yBytes           十六进制形式的公钥y分量,如果是SM2算法,应该是32字节 | ||||
|      * @param curve            EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||
|      * @param xBytes 十六进制形式的公钥x分量,如果是SM2算法,应该是32字节 | ||||
|      * @param yBytes 十六进制形式的公钥y分量,如果是SM2算法,应该是32字节 | ||||
|      * @param curve EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||
|      * @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS} | ||||
|      * @return | ||||
|      */ | ||||
|     public static ECPublicKeyParameters createECPublicKeyParameters( | ||||
|             byte[] xBytes, byte[] yBytes, ECCurve curve, ECDomainParameters domainParameters) { | ||||
|     public static ECPublicKeyParameters createECPublicKeyParameters(byte[] xBytes, byte[] yBytes, | ||||
|             ECCurve curve, ECDomainParameters domainParameters) { | ||||
|         final byte uncompressedFlag = 0x04; | ||||
|         int curveLength = getCurveLength(domainParameters); | ||||
|         xBytes = fixToCurveLengthBytes(curveLength, xBytes); | ||||
| @ -180,44 +179,35 @@ public class BCECUtil { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param str              十六进制形式的公钥x分量,如果是SM2算法,应该是32字节 | ||||
|      * @param curve            EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||
|      * @param str 十六进制形式的公钥x分量,如果是SM2算法,应该是32字节 | ||||
|      * @param curve EC曲线参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#CURVE} | ||||
|      * @param domainParameters EC Domain参数,一般是固定的,如果是SM2算法的可参考{@link SM2Util#DOMAIN_PARAMS} | ||||
|      * @return | ||||
|      */ | ||||
| 
 | ||||
|     public static ECPublicKeyParameters createECPublicKeyFromStrParameters( | ||||
|             String str, ECCurve curve, ECDomainParameters domainParameters) { | ||||
|         return new ECPublicKeyParameters( | ||||
|                 curve.decodePoint(ByteUtils.fromHexString(str)), domainParameters); | ||||
|     public static ECPublicKeyParameters createECPublicKeyFromStrParameters(String str, | ||||
|             ECCurve curve, ECDomainParameters domainParameters) { | ||||
|         return new ECPublicKeyParameters(curve.decodePoint(ByteUtils.fromHexString(str)), | ||||
|                 domainParameters); | ||||
|     } | ||||
| 
 | ||||
|     public static ECPrivateKeyParameters convertPrivateKeyToParameters(BCECPrivateKey ecPriKey) { | ||||
|         ECParameterSpec parameterSpec = ecPriKey.getParameters(); | ||||
|         ECDomainParameters domainParameters = | ||||
|                 new ECDomainParameters( | ||||
|                         parameterSpec.getCurve(), | ||||
|                         parameterSpec.getG(), | ||||
|                         parameterSpec.getN(), | ||||
|                         parameterSpec.getH()); | ||||
|         ECDomainParameters domainParameters = new ECDomainParameters(parameterSpec.getCurve(), | ||||
|                 parameterSpec.getG(), parameterSpec.getN(), parameterSpec.getH()); | ||||
|         return new ECPrivateKeyParameters(ecPriKey.getD(), domainParameters); | ||||
|     } | ||||
| 
 | ||||
|     public static ECPublicKeyParameters convertPublicKeyToParameters(BCECPublicKey ecPubKey) { | ||||
|         ECParameterSpec parameterSpec = ecPubKey.getParameters(); | ||||
|         ECDomainParameters domainParameters = | ||||
|                 new ECDomainParameters( | ||||
|                         parameterSpec.getCurve(), | ||||
|                         parameterSpec.getG(), | ||||
|                         parameterSpec.getN(), | ||||
|                         parameterSpec.getH()); | ||||
|         ECDomainParameters domainParameters = new ECDomainParameters(parameterSpec.getCurve(), | ||||
|                 parameterSpec.getG(), parameterSpec.getN(), parameterSpec.getH()); | ||||
|         return new ECPublicKeyParameters(ecPubKey.getQ(), domainParameters); | ||||
|     } | ||||
| 
 | ||||
|     public static BCECPublicKey createPublicKeyFromSubjectPublicKeyInfo( | ||||
|             SubjectPublicKeyInfo subPubInfo) | ||||
|             throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException, | ||||
|             IOException { | ||||
|             SubjectPublicKeyInfo subPubInfo) throws NoSuchProviderException, | ||||
|             NoSuchAlgorithmException, InvalidKeySpecException, IOException { | ||||
|         return BCECUtil.convertX509ToECPublicKey( | ||||
|                 subPubInfo.toASN1Primitive().getEncoded(ASN1Encoding.DER)); | ||||
|     } | ||||
| @ -229,19 +219,18 @@ public class BCECUtil { | ||||
|      * @param pubKey 可以为空,但是如果为空的话得到的结果OpenSSL可能解析不了 | ||||
|      * @return | ||||
|      */ | ||||
|     public static byte[] convertECPrivateKeyToPKCS8( | ||||
|             ECPrivateKeyParameters priKey, ECPublicKeyParameters pubKey) { | ||||
|     public static byte[] convertECPrivateKeyToPKCS8(ECPrivateKeyParameters priKey, | ||||
|             ECPublicKeyParameters pubKey) { | ||||
|         ECDomainParameters domainParams = priKey.getParameters(); | ||||
|         ECParameterSpec spec = | ||||
|                 new ECParameterSpec( | ||||
|                         domainParams.getCurve(), domainParams.getG(), domainParams.getN(), domainParams.getH()); | ||||
|         ECParameterSpec spec = new ECParameterSpec(domainParams.getCurve(), domainParams.getG(), | ||||
|                 domainParams.getN(), domainParams.getH()); | ||||
|         BCECPublicKey publicKey = 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 = | ||||
|                 new BCECPrivateKey( | ||||
|                         ALGO_NAME_EC, priKey, publicKey, spec, BouncyCastleProvider.CONFIGURATION); | ||||
|         BCECPrivateKey privateKey = new BCECPrivateKey(ALGO_NAME_EC, priKey, publicKey, spec, | ||||
|                 BouncyCastleProvider.CONFIGURATION); | ||||
|         return privateKey.getEncoded(); | ||||
|     } | ||||
| 
 | ||||
| @ -292,8 +281,8 @@ public class BCECUtil { | ||||
|      * @return | ||||
|      * @throws IOException | ||||
|      */ | ||||
|     public static byte[] convertECPrivateKeyToSEC1( | ||||
|             ECPrivateKeyParameters priKey, ECPublicKeyParameters pubKey) throws IOException { | ||||
|     public static byte[] convertECPrivateKeyToSEC1(ECPrivateKeyParameters priKey, | ||||
|             ECPublicKeyParameters pubKey) throws IOException { | ||||
|         byte[] pkcs8Bytes = convertECPrivateKeyToPKCS8(priKey, pubKey); | ||||
|         PrivateKeyInfo pki = PrivateKeyInfo.getInstance(pkcs8Bytes); | ||||
|         ASN1Encodable encodable = pki.parsePrivateKey(); | ||||
| @ -368,9 +357,8 @@ public class BCECUtil { | ||||
|      */ | ||||
|     public static byte[] convertECPublicKeyToX509(ECPublicKeyParameters pubKey) { | ||||
|         ECDomainParameters domainParams = pubKey.getParameters(); | ||||
|         ECParameterSpec spec = | ||||
|                 new ECParameterSpec( | ||||
|                         domainParams.getCurve(), domainParams.getG(), domainParams.getN(), domainParams.getH()); | ||||
|         ECParameterSpec spec = new ECParameterSpec(domainParams.getCurve(), domainParams.getG(), | ||||
|                 domainParams.getN(), domainParams.getH()); | ||||
|         BCECPublicKey publicKey = | ||||
|                 new BCECPublicKey(ALGO_NAME_EC, pubKey, spec, BouncyCastleProvider.CONFIGURATION); | ||||
|         return publicKey.getEncoded(); | ||||
| @ -473,23 +461,18 @@ public class BCECUtil { | ||||
|         } else { | ||||
|             ECCurve curve = EC5Util.convertCurve(ecSpec.getCurve()); | ||||
| 
 | ||||
|             X9ECParameters ecP = | ||||
|                     new X9ECParameters( | ||||
|                             curve, | ||||
|                             new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), withCompression), | ||||
|                             ecSpec.getOrder(), | ||||
|                             BigInteger.valueOf(ecSpec.getCofactor()), | ||||
|                             ecSpec.getCurve().getSeed()); | ||||
|             X9ECParameters ecP = new X9ECParameters(curve, | ||||
|                     new X9ECPoint(EC5Util.convertPoint(curve, ecSpec.getGenerator()), | ||||
|                             withCompression), | ||||
|                     ecSpec.getOrder(), BigInteger.valueOf(ecSpec.getCofactor()), | ||||
|                     ecSpec.getCurve().getSeed()); | ||||
| 
 | ||||
|             //// 如果是1.62或更低版本的bcprov-jdk15on应该使用以下这段代码,因为高版本的EC5Util.convertPoint没有向下兼容 | ||||
|       /* | ||||
|       X9ECParameters ecP = new X9ECParameters( | ||||
|           curve, | ||||
|           EC5Util.convertPoint(curve, ecSpec.getGenerator(), withCompression), | ||||
|           ecSpec.getOrder(), | ||||
|           BigInteger.valueOf(ecSpec.getCofactor()), | ||||
|           ecSpec.getCurve().getSeed()); | ||||
|       */ | ||||
|             /* | ||||
|              * X9ECParameters ecP = new X9ECParameters( curve, EC5Util.convertPoint(curve, | ||||
|              * ecSpec.getGenerator(), withCompression), ecSpec.getOrder(), | ||||
|              * BigInteger.valueOf(ecSpec.getCofactor()), ecSpec.getCurve().getSeed()); | ||||
|              */ | ||||
| 
 | ||||
|             params = new X962Parameters(ecP); | ||||
|         } | ||||
|  | ||||
| @ -7,51 +7,53 @@ import java.util.Arrays; | ||||
| 
 | ||||
| public class SM2KeyExchangeUtil { | ||||
|     /** | ||||
|      * @param initiator         true表示发起方,false表示响应方 | ||||
|      * @param keyBits           生成的密钥长度 | ||||
|      * @param selfStaticPriv    己方固定私钥 | ||||
|      * @param initiator true表示发起方,false表示响应方 | ||||
|      * @param keyBits 生成的密钥长度 | ||||
|      * @param selfStaticPriv 己方固定私钥 | ||||
|      * @param selfEphemeralPriv 己方临时私钥 | ||||
|      * @param selfId            己方ID | ||||
|      * @param otherStaticPub    对方固定公钥 | ||||
|      * @param selfId 己方ID | ||||
|      * @param otherStaticPub 对方固定公钥 | ||||
|      * @param otherEphemeralPub 对方临时公钥 | ||||
|      * @param otherId           对方ID | ||||
|      * @param otherId 对方ID | ||||
|      * @return 返回协商出的密钥,但是这个密钥是没有经过确认的 | ||||
|      */ | ||||
|     public static byte[] calculateKey(boolean initiator, int keyBits, | ||||
|                                       ECPrivateKeyParameters selfStaticPriv, ECPrivateKeyParameters selfEphemeralPriv, byte[] selfId, | ||||
|                                       ECPublicKeyParameters otherStaticPub, ECPublicKeyParameters otherEphemeralPub, byte[] otherId) { | ||||
|             ECPrivateKeyParameters selfStaticPriv, ECPrivateKeyParameters selfEphemeralPriv, | ||||
|             byte[] selfId, ECPublicKeyParameters otherStaticPub, | ||||
|             ECPublicKeyParameters otherEphemeralPub, byte[] otherId) { | ||||
|         SM2KeyExchange exch = new SM2KeyExchange(); | ||||
|         exch.init(new ParametersWithID( | ||||
|             new SM2KeyExchangePrivateParameters(initiator, selfStaticPriv, selfEphemeralPriv), | ||||
|             selfId)); | ||||
|         return exch.calculateKey( | ||||
|             keyBits, | ||||
|             new ParametersWithID(new SM2KeyExchangePublicParameters(otherStaticPub, otherEphemeralPub), otherId)); | ||||
|                 new SM2KeyExchangePrivateParameters(initiator, selfStaticPriv, selfEphemeralPriv), | ||||
|                 selfId)); | ||||
|         return exch.calculateKey(keyBits, new ParametersWithID( | ||||
|                 new SM2KeyExchangePublicParameters(otherStaticPub, otherEphemeralPub), otherId)); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param initiator         true表示发起方,false表示响应方 | ||||
|      * @param keyBits           生成的密钥长度 | ||||
|      * @param confirmationTag   确认信息,如果是响应方可以为null;如果是发起方则应为响应方的s1 | ||||
|      * @param selfStaticPriv    己方固定私钥 | ||||
|      * @param initiator true表示发起方,false表示响应方 | ||||
|      * @param keyBits 生成的密钥长度 | ||||
|      * @param confirmationTag 确认信息,如果是响应方可以为null;如果是发起方则应为响应方的s1 | ||||
|      * @param selfStaticPriv 己方固定私钥 | ||||
|      * @param selfEphemeralPriv 己方临时私钥 | ||||
|      * @param selfId            己方ID | ||||
|      * @param otherStaticPub    对方固定公钥 | ||||
|      * @param selfId 己方ID | ||||
|      * @param otherStaticPub 对方固定公钥 | ||||
|      * @param otherEphemeralPub 对方临时公钥 | ||||
|      * @param otherId           对方ID | ||||
|      * @param otherId 对方ID | ||||
|      * @return | ||||
|      */ | ||||
|     public static ExchangeResult calculateKeyWithConfirmation(boolean initiator, int keyBits, byte[] confirmationTag, | ||||
|                                                               ECPrivateKeyParameters selfStaticPriv, ECPrivateKeyParameters selfEphemeralPriv, byte[] selfId, | ||||
|                                                               ECPublicKeyParameters otherStaticPub, ECPublicKeyParameters otherEphemeralPub, byte[] otherId) { | ||||
|     public static ExchangeResult calculateKeyWithConfirmation(boolean initiator, int keyBits, | ||||
|             byte[] confirmationTag, ECPrivateKeyParameters selfStaticPriv, | ||||
|             ECPrivateKeyParameters selfEphemeralPriv, byte[] selfId, | ||||
|             ECPublicKeyParameters otherStaticPub, ECPublicKeyParameters otherEphemeralPub, | ||||
|             byte[] otherId) { | ||||
|         SM2KeyExchange exch = new SM2KeyExchange(); | ||||
|         exch.init(new ParametersWithID( | ||||
|             new SM2KeyExchangePrivateParameters(initiator, selfStaticPriv, selfEphemeralPriv), | ||||
|             selfId)); | ||||
|         byte[][] result = exch.calculateKeyWithConfirmation( | ||||
|             keyBits, | ||||
|             confirmationTag, | ||||
|             new ParametersWithID(new SM2KeyExchangePublicParameters(otherStaticPub, otherEphemeralPub), otherId)); | ||||
|                 new SM2KeyExchangePrivateParameters(initiator, selfStaticPriv, selfEphemeralPriv), | ||||
|                 selfId)); | ||||
|         byte[][] result = exch.calculateKeyWithConfirmation(keyBits, confirmationTag, | ||||
|                 new ParametersWithID( | ||||
|                         new SM2KeyExchangePublicParameters(otherStaticPub, otherEphemeralPub), | ||||
|                         otherId)); | ||||
|         ExchangeResult confirmResult = new ExchangeResult(); | ||||
|         confirmResult.setKey(result[0]); | ||||
|         if (initiator) { | ||||
|  | ||||
| @ -32,15 +32,14 @@ public class SM2KeyPair { | ||||
|         JsonObject jo = JsonParser.parseString(jsonStr).getAsJsonObject(); | ||||
|         String publicKeyStr = jo.get("publicKey").getAsString(); | ||||
|         String privateKeyStr = jo.get("privateKey").getAsString(); | ||||
|         ECPublicKeyParameters point = | ||||
|                 BCECUtil.createECPublicKeyFromStrParameters( | ||||
|                         publicKeyStr, SM2Util.CURVE, SM2Util.DOMAIN_PARAMS); | ||||
|         ECPublicKeyParameters point = BCECUtil.createECPublicKeyFromStrParameters(publicKeyStr, | ||||
|                 SM2Util.CURVE, SM2Util.DOMAIN_PARAMS); | ||||
|         return new SM2KeyPair(point, new BigInteger(privateKeyStr, 16)); | ||||
|     } | ||||
| 
 | ||||
|     public static ECPublicKeyParameters publicKeyStr2ECPoint(String pubKey) { | ||||
|         return BCECUtil.createECPublicKeyFromStrParameters( | ||||
|                 pubKey, SM2Util.CURVE, SM2Util.DOMAIN_PARAMS); | ||||
|         return BCECUtil.createECPublicKeyFromStrParameters(pubKey, SM2Util.CURVE, | ||||
|                 SM2Util.DOMAIN_PARAMS); | ||||
|     } | ||||
| 
 | ||||
|     public ECPublicKeyParameters getPublicKey() { | ||||
| @ -74,29 +73,16 @@ public class SM2KeyPair { | ||||
| 
 | ||||
|     public KeyPair toJavaSecurity() { | ||||
|         ECDomainParameters domainParams = privateKey.getParameters(); | ||||
|         ECParameterSpec spec = | ||||
|                 new ECParameterSpec( | ||||
|                         domainParams.getCurve(), | ||||
|                         domainParams.getG(), | ||||
|                         domainParams.getN(), | ||||
|                         domainParams.getH()); | ||||
|         ECParameterSpec spec = new ECParameterSpec(domainParams.getCurve(), domainParams.getG(), | ||||
|                 domainParams.getN(), domainParams.getH()); | ||||
|         BCECPublicKey bcPublicKey = null; | ||||
|         BCECPrivateKey bcPrivateKey; | ||||
|         if (null != publicKey) { | ||||
|             bcPublicKey = | ||||
|                     new BCECPublicKey( | ||||
|                             BCECUtil.ALGO_NAME_EC, | ||||
|                             publicKey, | ||||
|                             spec, | ||||
|                             BouncyCastleProvider.CONFIGURATION); | ||||
|             bcPublicKey = new BCECPublicKey(BCECUtil.ALGO_NAME_EC, publicKey, spec, | ||||
|                     BouncyCastleProvider.CONFIGURATION); | ||||
|         } | ||||
|         bcPrivateKey = | ||||
|                 new BCECPrivateKey( | ||||
|                         BCECUtil.ALGO_NAME_EC, | ||||
|                         privateKey, | ||||
|                         bcPublicKey, | ||||
|                         spec, | ||||
|                         BouncyCastleProvider.CONFIGURATION); | ||||
|         bcPrivateKey = new BCECPrivateKey(BCECUtil.ALGO_NAME_EC, privateKey, bcPublicKey, spec, | ||||
|                 BouncyCastleProvider.CONFIGURATION); | ||||
|         return new KeyPair(bcPublicKey, bcPrivateKey); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -20,7 +20,7 @@ import java.math.BigInteger; | ||||
|  * 有的国密需求是用户可以自己做预处理,签名验签只是对预处理的结果进行签名和验签 | ||||
|  */ | ||||
| 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 Digest digest = null; | ||||
| @ -44,11 +44,12 @@ public class SM2PreprocessSigner implements ECConstants { | ||||
|      * 初始化 | ||||
|      * | ||||
|      * @param forSigning true表示用于签名,false表示用于验签 | ||||
|      * @param digest     SM2算法的话,一般是采用SM3摘要算法 | ||||
|      * @param digest SM2算法的话,一般是采用SM3摘要算法 | ||||
|      * @param param | ||||
|      * @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; | ||||
| 
 | ||||
|         if (digest.getDigestSize() != DIGEST_LENGTH) { | ||||
| @ -76,7 +77,8 @@ public class SM2PreprocessSigner implements ECConstants { | ||||
|                 ecParams = ecKey.getParameters(); | ||||
|                 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 { | ||||
|             ecKey = (ECKeyParameters) baseParam; | ||||
|             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 | ||||
|      */ | ||||
| @ -126,7 +125,7 @@ public class SM2PreprocessSigner implements ECConstants { | ||||
| 
 | ||||
|         ECMultiplier basePointMultiplier = createBasePointMultiplier(); | ||||
| 
 | ||||
|         // 5.2.1 Draft RFC:  SM2 Public Key Algorithms | ||||
|         // 5.2.1 Draft RFC: SM2 Public Key Algorithms | ||||
|         do // generate s | ||||
|         { | ||||
|             BigInteger k; | ||||
| @ -140,16 +139,14 @@ public class SM2PreprocessSigner implements ECConstants { | ||||
| 
 | ||||
|                 // A5 | ||||
|                 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 | ||||
|             BigInteger dPlus1ModN = d.add(ONE).modInverse(n); | ||||
| 
 | ||||
|             s = k.subtract(r.multiply(d)).mod(n); | ||||
|             s = dPlus1ModN.multiply(s).mod(n); | ||||
|         } | ||||
|         while (s.equals(ZERO)); | ||||
|         } while (s.equals(ZERO)); | ||||
| 
 | ||||
|         // A7 | ||||
|         try { | ||||
| @ -162,7 +159,7 @@ public class SM2PreprocessSigner implements ECConstants { | ||||
|     private boolean verifySignature(byte[] eHash, BigInteger r, BigInteger s) { | ||||
|         BigInteger n = ecParams.getN(); | ||||
| 
 | ||||
|         // 5.3.1 Draft RFC:  SM2 Public Key Algorithms | ||||
|         // 5.3.1 Draft RFC: SM2 Public Key Algorithms | ||||
|         // B1 | ||||
|         if (r.compareTo(ONE) < 0 || r.compareTo(n) >= 0) { | ||||
|             return false; | ||||
| @ -245,8 +242,7 @@ public class SM2PreprocessSigner implements ECConstants { | ||||
|         return new BigInteger(1, message); | ||||
|     } | ||||
| 
 | ||||
|     protected BigInteger[] derDecode(byte[] encoding) | ||||
|             throws IOException { | ||||
|     protected BigInteger[] derDecode(byte[] encoding) throws IOException { | ||||
|         ASN1Sequence seq = ASN1Sequence.getInstance(ASN1Primitive.fromByteArray(encoding)); | ||||
|         if (seq.size() != 2) { | ||||
|             return null; | ||||
| @ -260,11 +256,10 @@ public class SM2PreprocessSigner implements ECConstants { | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         return new BigInteger[]{r, s}; | ||||
|         return new BigInteger[] {r, s}; | ||||
|     } | ||||
| 
 | ||||
|     protected byte[] derEncode(BigInteger r, BigInteger s) | ||||
|             throws IOException { | ||||
|     protected byte[] derEncode(BigInteger r, BigInteger s) throws IOException { | ||||
| 
 | ||||
|         ASN1EncodableVector v = new ASN1EncodableVector(); | ||||
|         v.add(new ASN1Integer(r)); | ||||
|  | ||||
| @ -19,195 +19,196 @@ import org.bouncycastle.util.encoders.Hex; | ||||
| import java.math.BigInteger; | ||||
| 
 | ||||
| public class SM2Signer implements Signer, ECConstants { | ||||
|   private final DSAKCalculator kCalculator; | ||||
|   private final Digest digest; | ||||
|   private final DSAEncoding encoding; | ||||
|   private ECDomainParameters ecParams; | ||||
|   private ECPoint pubPoint; | ||||
|   private ECKeyParameters ecKey; | ||||
|   private byte[] z; | ||||
|     private final DSAKCalculator kCalculator; | ||||
|     private final Digest digest; | ||||
|     private final DSAEncoding encoding; | ||||
|     private ECDomainParameters ecParams; | ||||
|     private ECPoint pubPoint; | ||||
|     private ECKeyParameters ecKey; | ||||
|     private byte[] z; | ||||
| 
 | ||||
|   public SM2Signer() { | ||||
|     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"); | ||||
|     public SM2Signer() { | ||||
|         this(StandardDSAEncoding.INSTANCE, new SM3Digest()); | ||||
|     } | ||||
| 
 | ||||
|     if (var1) { | ||||
|       if (var3 instanceof ParametersWithRandom) { | ||||
|         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(); | ||||
|     public SM2Signer(Digest var1) { | ||||
|         this(StandardDSAEncoding.INSTANCE, var1); | ||||
|     } | ||||
| 
 | ||||
|     this.z = this.getZ(var4); | ||||
|     this.digest.update(this.z, 0, this.z.length); | ||||
|   } | ||||
| 
 | ||||
|   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 SM2Signer(DSAEncoding var1) { | ||||
|         this.kCalculator = new RandomDSAKCalculator(); | ||||
|         this.encoding = var1; | ||||
|         this.digest = new SM3Digest(); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   public void reset() { | ||||
|     this.digest.reset(); | ||||
|     if (this.z != null) { | ||||
|       this.digest.update(this.z, 0, this.z.length); | ||||
|     public SM2Signer(DSAEncoding var1, Digest var2) { | ||||
|         this.kCalculator = new RandomDSAKCalculator(); | ||||
|         this.encoding = var1; | ||||
|         this.digest = var2; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   public byte[] generateSignature() throws CryptoException { | ||||
|     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(); | ||||
| 
 | ||||
|     while (true) { | ||||
|       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; | ||||
|     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 { | ||||
|           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); | ||||
|           } | ||||
|             var3 = var2; | ||||
|             var4 = Hex.decodeStrict("31323334353637383132333435363738"); | ||||
|         } | ||||
|       } else { | ||||
|         return false; | ||||
|       } | ||||
|     } else { | ||||
|       return false; | ||||
| 
 | ||||
|         if (var1) { | ||||
|             if (var3 instanceof ParametersWithRandom) { | ||||
|                 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); | ||||
|         this.digest.update(this.z, 0, this.z.length); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   private byte[] digestDoFinal() { | ||||
|     byte[] var1 = new byte[this.digest.getDigestSize()]; | ||||
|     this.digest.doFinal(var1, 0); | ||||
|     this.reset(); | ||||
|     return var1; | ||||
|   } | ||||
|     public void update(byte var1) { | ||||
|         this.digest.update(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; | ||||
|   } | ||||
|     public void update(byte[] var1, int var2, int var3) { | ||||
|         this.digest.update(var1, var2, var3); | ||||
|     } | ||||
| 
 | ||||
|   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); | ||||
|   } | ||||
|     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; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   private void addFieldElement(Digest var1, ECFieldElement var2) { | ||||
|     byte[] var3 = var2.getEncoded(); | ||||
|     var1.update(var3, 0, var3.length); | ||||
|   } | ||||
|     public void reset() { | ||||
|         this.digest.reset(); | ||||
|         if (this.z != null) { | ||||
|             this.digest.update(this.z, 0, this.z.length); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|   protected ECMultiplier createBasePointMultiplier() { | ||||
|     return new FixedPointCombMultiplier(); | ||||
|   } | ||||
|     public byte[] generateSignature() throws CryptoException { | ||||
|         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) { | ||||
|     return new BigInteger(1, var2); | ||||
|   } | ||||
|         while (true) { | ||||
|             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 = | ||||
|             new EllipticCurve(new ECFieldFp(SM2_ECC_P), SM2_ECC_A, SM2_ECC_B); | ||||
|     public static final java.security.spec.ECPoint JDK_G_POINT = | ||||
|             new java.security.spec.ECPoint( | ||||
|                     G_POINT.getAffineXCoord().toBigInteger(), | ||||
|                     G_POINT.getAffineYCoord().toBigInteger()); | ||||
|     public static final java.security.spec.ECPoint JDK_G_POINT = new java.security.spec.ECPoint( | ||||
|             G_POINT.getAffineXCoord().toBigInteger(), G_POINT.getAffineYCoord().toBigInteger()); | ||||
|     public static final java.security.spec.ECParameterSpec JDK_EC_SPEC = | ||||
|             new java.security.spec.ECParameterSpec( | ||||
|                     JDK_CURVE, JDK_G_POINT, SM2_ECC_N, SM2_ECC_H.intValue()); | ||||
|             new java.security.spec.ECParameterSpec(JDK_CURVE, JDK_G_POINT, SM2_ECC_N, | ||||
|                     SM2_ECC_H.intValue()); | ||||
|     public static final int SM3_DIGEST_LENGTH = 32; | ||||
| 
 | ||||
|     ////////////////////////////////////////////////////////////////////////////////////// | ||||
|     static ECCurve.Fp SM2_ECC_FP = | ||||
|             new ECCurve.Fp( | ||||
|                     SM2_ECC_P, // q | ||||
|                     SM2_ECC_A, // a | ||||
|                     SM2_ECC_B); // b | ||||
|     static ECCurve.Fp SM2_ECC_FP = new ECCurve.Fp(SM2_ECC_P, // q | ||||
|             SM2_ECC_A, // a | ||||
|             SM2_ECC_B); // b | ||||
| 
 | ||||
|     /** | ||||
|      * 生成ECC密钥对 | ||||
| @ -79,9 +75,8 @@ public class SM2Util extends GMBaseUtil { | ||||
|      * @throws NoSuchAlgorithmException | ||||
|      * @throws InvalidAlgorithmParameterException | ||||
|      */ | ||||
|     public static KeyPair generateKeyPair(SecureRandom random) | ||||
|             throws NoSuchProviderException, NoSuchAlgorithmException, | ||||
|             InvalidAlgorithmParameterException { | ||||
|     public static KeyPair generateKeyPair(SecureRandom random) throws NoSuchProviderException, | ||||
|             NoSuchAlgorithmException, InvalidAlgorithmParameterException { | ||||
|         return BCECUtil.generateKeyPair(DOMAIN_PARAMS, random); | ||||
|     } | ||||
| 
 | ||||
| @ -95,9 +90,8 @@ public class SM2Util extends GMBaseUtil { | ||||
|             BCECPrivateKey privateKey = (BCECPrivateKey) key.getPrivate(); | ||||
|             BCECPublicKey publicKey = (BCECPublicKey) key.getPublic(); | ||||
|             byte[] point = publicKey.getQ().getEncoded(false); | ||||
|             ECPublicKeyParameters parameters = | ||||
|                     BCECUtil.createECPublicKeyFromStrParameters( | ||||
|                             ByteUtils.toHexString(point), CURVE, DOMAIN_PARAMS); | ||||
|             ECPublicKeyParameters parameters = BCECUtil.createECPublicKeyFromStrParameters( | ||||
|                     ByteUtils.toHexString(point), CURVE, DOMAIN_PARAMS); | ||||
|             return new SM2KeyPair(parameters, privateKey.getD()); | ||||
|         } catch (Exception e) { | ||||
|             e.printStackTrace(); | ||||
| @ -129,7 +123,7 @@ public class SM2Util extends GMBaseUtil { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param pubKey  公钥 | ||||
|      * @param pubKey 公钥 | ||||
|      * @param srcData 原文 | ||||
|      * @return 默认输出C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @throws InvalidCipherTextException | ||||
| @ -141,8 +135,8 @@ public class SM2Util extends GMBaseUtil { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param mode    指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param pubKey  公钥 | ||||
|      * @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param pubKey 公钥 | ||||
|      * @param srcData 原文 | ||||
|      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @throws InvalidCipherTextException | ||||
| @ -155,7 +149,7 @@ public class SM2Util extends GMBaseUtil { | ||||
| 
 | ||||
|     /** | ||||
|      * @param pubKeyParameters 公钥 | ||||
|      * @param srcData          原文 | ||||
|      * @param srcData 原文 | ||||
|      * @return 默认输出C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @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 srcData          原文 | ||||
|      * @param srcData 原文 | ||||
|      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @throws InvalidCipherTextException | ||||
|      */ | ||||
| @ -180,8 +174,9 @@ public class SM2Util extends GMBaseUtil { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param priKey    私钥 | ||||
|      * @param sm2Cipher 默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @param priKey 私钥 | ||||
|      * @param sm2Cipher | ||||
|      *        默认输入C1C3C2顺序的密文。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。 | ||||
|      * @throws InvalidCipherTextException | ||||
|      */ | ||||
| @ -192,9 +187,10 @@ public class SM2Util extends GMBaseUtil { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param mode      指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param priKey    私钥 | ||||
|      * @param sm2Cipher 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param priKey 私钥 | ||||
|      * @param sm2Cipher | ||||
|      *        根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @return 原文。SM2解密返回了数据则一定是原文,因为SM2自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。 | ||||
|      * @throws InvalidCipherTextException | ||||
|      */ | ||||
| @ -206,7 +202,8 @@ public class SM2Util extends GMBaseUtil { | ||||
| 
 | ||||
|     /** | ||||
|      * @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自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。 | ||||
|      * @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 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自带校验,如果密文被篡改或者密钥对不上,都是会直接报异常的。 | ||||
|      * @throws InvalidCipherTextException | ||||
|      */ | ||||
|     public static byte[] decrypt( | ||||
|             Mode mode, ECPrivateKeyParameters priKeyParameters, byte[] sm2Cipher) | ||||
|             throws InvalidCipherTextException { | ||||
|     public static byte[] decrypt(Mode mode, ECPrivateKeyParameters priKeyParameters, | ||||
|             byte[] sm2Cipher) throws InvalidCipherTextException { | ||||
|         SM2Engine engine = new SM2Engine(mode); | ||||
|         engine.init(false, priKeyParameters); | ||||
|         if (sm2Cipher[0] != 4) { | ||||
| @ -239,7 +236,8 @@ public class SM2Util extends GMBaseUtil { | ||||
|     /** | ||||
|      * 分解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 | ||||
|      * @throws Exception | ||||
|      */ | ||||
| @ -251,8 +249,9 @@ public class SM2Util extends GMBaseUtil { | ||||
|     /** | ||||
|      * 分解SM2密文 | ||||
|      * | ||||
|      * @param mode       指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param cipherText 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param cipherText | ||||
|      *        根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @return | ||||
|      */ | ||||
|     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 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 | ||||
|      * @throws Exception | ||||
|      */ | ||||
| @ -275,14 +275,15 @@ public class SM2Util extends GMBaseUtil { | ||||
|     /** | ||||
|      * 分解SM2密文 | ||||
|      * | ||||
|      * @param mode         指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param curveLength  曲线长度,SM2的话就是256位。 | ||||
|      * @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param curveLength 曲线长度,SM2的话就是256位。 | ||||
|      * @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 | ||||
|      */ | ||||
|     public static SM2Cipher parseSM2Cipher( | ||||
|             Mode mode, int curveLength, int digestLength, byte[] cipherText) throws Exception { | ||||
|     public static SM2Cipher parseSM2Cipher(Mode mode, int curveLength, int digestLength, | ||||
|             byte[] cipherText) throws Exception { | ||||
|         byte[] c1 = new byte[curveLength * 2 + 1]; | ||||
|         byte[] c2 = new byte[cipherText.length - c1.length - digestLength]; | ||||
|         byte[] c3 = new byte[digestLength]; | ||||
| @ -321,8 +322,9 @@ public class SM2Util extends GMBaseUtil { | ||||
|     /** | ||||
|      * DER编码密文 | ||||
|      * | ||||
|      * @param mode   指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param cipher 根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param cipher | ||||
|      *        根据mode不同,需要输入的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @return 按指定mode DER编码后的密文 | ||||
|      * @throws Exception | ||||
|      */ | ||||
| @ -334,9 +336,9 @@ public class SM2Util extends GMBaseUtil { | ||||
|     /** | ||||
|      * DER编码密文 | ||||
|      * | ||||
|      * @param curveLength  曲线长度,SM2的话就是256位。 | ||||
|      * @param curveLength 曲线长度,SM2的话就是256位。 | ||||
|      * @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编码的结果 | ||||
|      * @throws IOException | ||||
|      */ | ||||
| @ -346,15 +348,16 @@ public class SM2Util extends GMBaseUtil { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param mode         指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param curveLength  曲线长度,SM2的话就是256位。 | ||||
|      * @param mode 指定密文结构,旧标准的为C1C2C3,新的[《SM2密码算法使用规范》 GM/T 0009-2012]标准为C1C3C2 | ||||
|      * @param curveLength 曲线长度,SM2的话就是256位。 | ||||
|      * @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编码后的密文 | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     public static byte[] encodeSM2CipherToDER( | ||||
|             Mode mode, int curveLength, int digestLength, byte[] cipher) throws Exception { | ||||
|     public static byte[] encodeSM2CipherToDER(Mode mode, int curveLength, int digestLength, | ||||
|             byte[] cipher) throws Exception { | ||||
| 
 | ||||
|         byte[] c1x = new byte[curveLength]; | ||||
|         byte[] c1y = new byte[curveLength]; | ||||
| @ -379,8 +382,8 @@ public class SM2Util extends GMBaseUtil { | ||||
|         } | ||||
| 
 | ||||
|         ASN1Encodable[] arr = new ASN1Encodable[4]; | ||||
|         arr[0] = new ASN1Integer(new BigInteger(1,c1x)); | ||||
|         arr[1] = new ASN1Integer(new BigInteger(1,c1y)); | ||||
|         arr[0] = new ASN1Integer(new BigInteger(1, c1x)); | ||||
|         arr[1] = new ASN1Integer(new BigInteger(1, c1y)); | ||||
|         if (mode == Mode.C1C2C3) { | ||||
|             arr[2] = new DEROctetString(c2); | ||||
|             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编码后的密文 | ||||
|      * @return 根据mode不同,输出的密文C1C2C3排列顺序不同。C1为65字节第1字节为压缩标识,这里固定为0x04,后面64字节为xy分量各32字节。C3为32字节。C2长度与原文一致。 | ||||
|      * @throws Exception | ||||
| @ -450,7 +453,7 @@ public class SM2Util extends GMBaseUtil { | ||||
|     /** | ||||
|      * 签名 | ||||
|      * | ||||
|      * @param priKey  私钥 | ||||
|      * @param priKey 私钥 | ||||
|      * @param srcData 原文 | ||||
|      * @return DER编码后的签名值 | ||||
|      * @throws CryptoException | ||||
| @ -464,7 +467,7 @@ public class SM2Util extends GMBaseUtil { | ||||
|      * 签名 不指定withId,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * | ||||
|      * @param priKeyParameters 私钥 | ||||
|      * @param srcData          原文 | ||||
|      * @param srcData 原文 | ||||
|      * @return DER编码后的签名值 | ||||
|      * @throws CryptoException | ||||
|      */ | ||||
| @ -476,8 +479,8 @@ public class SM2Util extends GMBaseUtil { | ||||
|     /** | ||||
|      * 私钥签名 | ||||
|      * | ||||
|      * @param priKey  私钥 | ||||
|      * @param withId  可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * @param priKey 私钥 | ||||
|      * @param withId 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * @param srcData 原文 | ||||
|      * @return DER编码后的签名值 | ||||
|      * @throws CryptoException | ||||
| @ -492,14 +495,13 @@ public class SM2Util extends GMBaseUtil { | ||||
|      * 签名 | ||||
|      * | ||||
|      * @param priKeyParameters 私钥 | ||||
|      * @param withId           可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * @param srcData          源数据 | ||||
|      * @param withId 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * @param srcData 源数据 | ||||
|      * @return DER编码后的签名值 | ||||
|      * @throws CryptoException | ||||
|      */ | ||||
|     public static byte[] sign( | ||||
|             ECPrivateKeyParameters priKeyParameters, byte[] withId, byte[] srcData) | ||||
|             throws CryptoException { | ||||
|     public static byte[] sign(ECPrivateKeyParameters priKeyParameters, byte[] withId, | ||||
|             byte[] srcData) throws CryptoException { | ||||
|         SM2Signer signer = new SM2Signer(); | ||||
|         CipherParameters param = null; | ||||
|         ParametersWithRandom pwr = new ParametersWithRandom(priKeyParameters, new SecureRandom()); | ||||
| @ -576,22 +578,22 @@ public class SM2Util extends GMBaseUtil { | ||||
|      * 验签 不指定withId,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * | ||||
|      * @param pubKeyParameters 公钥 | ||||
|      * @param srcData          原文 | ||||
|      * @param sign             DER编码的签名值 | ||||
|      * @param srcData 原文 | ||||
|      * @param sign DER编码的签名值 | ||||
|      * @return 验签成功返回true,失败返回false | ||||
|      */ | ||||
|     public static boolean verify( | ||||
|             ECPublicKeyParameters pubKeyParameters, byte[] srcData, byte[] sign) { | ||||
|     public static boolean verify(ECPublicKeyParameters pubKeyParameters, byte[] srcData, | ||||
|             byte[] sign) { | ||||
|         return verify(pubKeyParameters, null, srcData, sign); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 验签 | ||||
|      * | ||||
|      * @param pubKey  公钥 | ||||
|      * @param withId  可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * @param pubKey 公钥 | ||||
|      * @param withId 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * @param srcData 原文 | ||||
|      * @param sign    DER编码的签名值 | ||||
|      * @param sign DER编码的签名值 | ||||
|      * @return | ||||
|      */ | ||||
|     public static boolean verify(BCECPublicKey pubKey, byte[] withId, byte[] srcData, byte[] sign) { | ||||
| @ -603,13 +605,13 @@ public class SM2Util extends GMBaseUtil { | ||||
|      * 验签 | ||||
|      * | ||||
|      * @param pubKeyParameters 公钥 | ||||
|      * @param withId           可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * @param srcData          原文 | ||||
|      * @param sign             DER编码的签名值 | ||||
|      * @param withId 可以为null,若为null,则默认withId为字节数组:"1234567812345678".getBytes() | ||||
|      * @param srcData 原文 | ||||
|      * @param sign DER编码的签名值 | ||||
|      * @return 验签成功返回true,失败返回false | ||||
|      */ | ||||
|     public static boolean verify( | ||||
|             ECPublicKeyParameters pubKeyParameters, byte[] withId, byte[] srcData, byte[] sign) { | ||||
|     public static boolean verify(ECPublicKeyParameters pubKeyParameters, byte[] withId, | ||||
|             byte[] srcData, byte[] sign) { | ||||
|         SM2Signer signer = new SM2Signer(); | ||||
|         CipherParameters param; | ||||
|         if (withId != null) { | ||||
| @ -647,13 +649,12 @@ public class SM2Util extends GMBaseUtil { | ||||
|             byte[] sigByte = ByteUtils.fromHexString(signature); | ||||
|             // TODO 是否需要der编码? | ||||
|             // try { | ||||
|             //   sigByte = SM2Util.encodeSM2SignToDER(sigByte); | ||||
|             // sigByte = SM2Util.encodeSM2SignToDER(sigByte); | ||||
|             // } catch (Exception e) { | ||||
|             //   e.printStackTrace(); | ||||
|             // e.printStackTrace(); | ||||
|             // } | ||||
|             ECPublicKeyParameters pubkey = | ||||
|                     BCECUtil.createECPublicKeyFromStrParameters( | ||||
|                             publicKey, SM2Util.CURVE, SM2Util.DOMAIN_PARAMS); | ||||
|             ECPublicKeyParameters pubkey = BCECUtil.createECPublicKeyFromStrParameters(publicKey, | ||||
|                     SM2Util.CURVE, SM2Util.DOMAIN_PARAMS); | ||||
|             boolean result = SM2Util.verify(pubkey, toVerify.getBytes(), sigByte); | ||||
|             return result; | ||||
|         } catch (Exception e) { | ||||
|  | ||||
| @ -41,7 +41,7 @@ public class SM3Util extends GMBaseUtil { | ||||
|     /** | ||||
|      * 计算SM3 Mac值 | ||||
|      * | ||||
|      * @param key     key值,可以是任意长度的字节数组 | ||||
|      * @param key key值,可以是任意长度的字节数组 | ||||
|      * @param srcData 原文 | ||||
|      * @return Mac值,对于HMac-SM3来说是32字节 | ||||
|      */ | ||||
|  | ||||
| @ -32,8 +32,10 @@ public class SM4Util extends GMBaseUtil { | ||||
|         return generateKey(DEFAULT_KEY_SIZE); | ||||
|     } | ||||
| 
 | ||||
|     public static byte[] generateKey(int keySize) throws NoSuchAlgorithmException, NoSuchProviderException { | ||||
|         KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME); | ||||
|     public static byte[] generateKey(int keySize) | ||||
|             throws NoSuchAlgorithmException, NoSuchProviderException { | ||||
|         KeyGenerator kg = | ||||
|                 KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME); | ||||
|         kg.init(keySize, new SecureRandom()); | ||||
|         return kg.generateKey().getEncoded(); | ||||
|     } | ||||
| @ -86,7 +88,8 @@ public class SM4Util extends GMBaseUtil { | ||||
|             throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, | ||||
|             NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, | ||||
|             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); | ||||
|     } | ||||
| 
 | ||||
| @ -94,18 +97,20 @@ public class SM4Util extends GMBaseUtil { | ||||
|             throws IllegalBlockSizeException, BadPaddingException, InvalidKeyException, | ||||
|             NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, | ||||
|             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); | ||||
|     } | ||||
| 
 | ||||
|     public static byte[] doCMac(byte[] key, byte[] data) throws NoSuchProviderException, NoSuchAlgorithmException, | ||||
|             InvalidKeyException { | ||||
|     public static byte[] doCMac(byte[] key, byte[] data) | ||||
|             throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { | ||||
|         Key keyObj = new SecretKeySpec(key, ALGORITHM_NAME); | ||||
|         return doMac("SM4-CMAC", keyObj, 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); | ||||
|     } | ||||
| 
 | ||||
| @ -119,7 +124,8 @@ public class SM4Util extends GMBaseUtil { | ||||
|      */ | ||||
|     public static byte[] doCBCMac(byte[] key, byte[] iv, byte[] data) { | ||||
|         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); | ||||
|     } | ||||
| 
 | ||||
| @ -131,19 +137,22 @@ public class SM4Util extends GMBaseUtil { | ||||
|      * @return | ||||
|      * @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(); | ||||
|         if (padding == null) { | ||||
|             if (data.length % engine.getBlockSize() != 0) { | ||||
|                 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); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     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); | ||||
|         mac.init(new ParametersWithIV(cipherParameters, iv)); | ||||
|         mac.update(data, 0, data.length); | ||||
| @ -152,8 +161,8 @@ public class SM4Util extends GMBaseUtil { | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     private static byte[] doMac(String algorithmName, Key key, byte[] data) throws NoSuchProviderException, | ||||
|             NoSuchAlgorithmException, InvalidKeyException { | ||||
|     private static byte[] doMac(String algorithmName, Key key, byte[] data) | ||||
|             throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeyException { | ||||
|         Mac mac = Mac.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME); | ||||
|         mac.init(key); | ||||
|         mac.update(data); | ||||
| @ -170,8 +179,8 @@ public class SM4Util extends GMBaseUtil { | ||||
|     } | ||||
| 
 | ||||
|     private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv) | ||||
|             throws InvalidKeyException, InvalidAlgorithmParameterException, NoSuchAlgorithmException, | ||||
|             NoSuchProviderException, NoSuchPaddingException { | ||||
|             throws InvalidKeyException, InvalidAlgorithmParameterException, | ||||
|             NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException { | ||||
|         Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME); | ||||
|         Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME); | ||||
|         IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); | ||||
|  | ||||
| @ -29,7 +29,8 @@ public class CommonUtil { | ||||
|      * @return | ||||
|      * @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) { | ||||
|             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, | ||||
|                                                        String signAlgo) throws OperatorCreationException { | ||||
|         PKCS10CertificationRequestBuilder csrBuilder = new JcaPKCS10CertificationRequestBuilder(subject, pubKey); | ||||
|     public static PKCS10CertificationRequest createCSR(X500Name subject, SM2PublicKey pubKey, | ||||
|             PrivateKey priKey, String signAlgo) throws OperatorCreationException { | ||||
|         PKCS10CertificationRequestBuilder csrBuilder = | ||||
|                 new JcaPKCS10CertificationRequestBuilder(subject, pubKey); | ||||
|         ContentSigner signerBuilder = new JcaContentSignerBuilder(signAlgo) | ||||
|             .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(priKey); | ||||
|                 .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(priKey); | ||||
|         return csrBuilder.build(signerBuilder); | ||||
|     } | ||||
| 
 | ||||
|     public static AlgorithmIdentifier findSignatureAlgorithmIdentifier(String algoName) { | ||||
|         DefaultSignatureAlgorithmIdentifierFinder sigFinder = new DefaultSignatureAlgorithmIdentifierFinder(); | ||||
|         DefaultSignatureAlgorithmIdentifierFinder sigFinder = | ||||
|                 new DefaultSignatureAlgorithmIdentifierFinder(); | ||||
|         return sigFinder.find(algoName); | ||||
|     } | ||||
| 
 | ||||
|     public static AlgorithmIdentifier findDigestAlgorithmIdentifier(String algoName) { | ||||
|         DefaultDigestAlgorithmIdentifierFinder digFinder = new DefaultDigestAlgorithmIdentifierFinder(); | ||||
|         DefaultDigestAlgorithmIdentifierFinder digFinder = | ||||
|                 new DefaultDigestAlgorithmIdentifierFinder(); | ||||
|         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[]  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; | ||||
| 
 | ||||
| @ -47,14 +47,15 @@ public class RandomSNAllocator implements CertSNAllocator { | ||||
| 
 | ||||
|     /** | ||||
|      * Constructor with the specification of bitLen. | ||||
|      *  | ||||
|      * @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]. | ||||
|      */ | ||||
|     public RandomSNAllocator(int bitLen) { | ||||
|         if (bitLen < MIN_SERIALNUMBER_SIZE || bitLen > MAX_SERIALNUMBER_SIZE) { | ||||
|             throw new IllegalArgumentException(String.format( | ||||
|                 "%s may not be out of the range [%d, %d]: %d", | ||||
|                 "bitLen", MIN_SERIALNUMBER_SIZE, MAX_SERIALNUMBER_SIZE, bitLen)); | ||||
|             throw new IllegalArgumentException( | ||||
|                     String.format("%s may not be out of the range [%d, %d]: %d", "bitLen", | ||||
|                             MIN_SERIALNUMBER_SIZE, MAX_SERIALNUMBER_SIZE, bitLen)); | ||||
|         } | ||||
| 
 | ||||
|         this.random = new SecureRandom(); | ||||
|  | ||||
| @ -33,17 +33,17 @@ public class SM2CertUtil { | ||||
|         ECPublicKey pubKey = (ECPublicKey) sm2Cert.getPublicKey(); | ||||
|         ECPoint q = pubKey.getQ(); | ||||
|         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); | ||||
|         return new BCECPublicKey(pubKey.getAlgorithm(), pubKeySpec, | ||||
|             BouncyCastleProvider.CONFIGURATION); | ||||
|                 BouncyCastleProvider.CONFIGURATION); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 校验证书 | ||||
|      * | ||||
|      * @param issuerPubKey 从颁发者CA证书中提取出来的公钥 | ||||
|      * @param cert         待校验的证书 | ||||
|      * @param cert 待校验的证书 | ||||
|      * @return | ||||
|      */ | ||||
|     public static boolean verifyCertificate(BCECPublicKey issuerPubKey, X509Certificate cert) { | ||||
| @ -55,8 +55,8 @@ public class SM2CertUtil { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
|     public static X509Certificate getX509Certificate(String certFilePath) throws IOException, CertificateException, | ||||
|             NoSuchProviderException { | ||||
|     public static X509Certificate getX509Certificate(String certFilePath) | ||||
|             throws IOException, CertificateException, NoSuchProviderException { | ||||
|         InputStream is = null; | ||||
|         try { | ||||
|             is = new FileInputStream(certFilePath); | ||||
| @ -68,20 +68,21 @@ public class SM2CertUtil { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static X509Certificate getX509Certificate(byte[] certBytes) throws CertificateException, | ||||
|             NoSuchProviderException { | ||||
|     public static X509Certificate getX509Certificate(byte[] certBytes) | ||||
|             throws CertificateException, NoSuchProviderException { | ||||
|         ByteArrayInputStream bais = new ByteArrayInputStream(certBytes); | ||||
|         return getX509Certificate(bais); | ||||
|     } | ||||
| 
 | ||||
|     public static X509Certificate getX509Certificate(InputStream is) throws CertificateException, | ||||
|             NoSuchProviderException { | ||||
|         CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); | ||||
|     public static X509Certificate getX509Certificate(InputStream is) | ||||
|             throws CertificateException, NoSuchProviderException { | ||||
|         CertificateFactory cf = | ||||
|                 CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); | ||||
|         return (X509Certificate) cf.generateCertificate(is); | ||||
|     } | ||||
| 
 | ||||
|     public static CertPath getCertificateChain(String certChainPath) throws IOException, CertificateException, | ||||
|             NoSuchProviderException { | ||||
|     public static CertPath getCertificateChain(String certChainPath) | ||||
|             throws IOException, CertificateException, NoSuchProviderException { | ||||
|         InputStream is = null; | ||||
|         try { | ||||
|             is = new FileInputStream(certChainPath); | ||||
| @ -93,30 +94,37 @@ public class SM2CertUtil { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static CertPath getCertificateChain(byte[] certChainBytes) throws CertificateException, | ||||
|             NoSuchProviderException { | ||||
|     public static CertPath getCertificateChain(byte[] certChainBytes) | ||||
|             throws CertificateException, NoSuchProviderException { | ||||
|         ByteArrayInputStream bais = new ByteArrayInputStream(certChainBytes); | ||||
|         return getCertificateChain(bais); | ||||
|     } | ||||
| 
 | ||||
|     public static byte[] getCertificateChainBytes(CertPath certChain) throws CertificateEncodingException { | ||||
|     public static byte[] getCertificateChainBytes(CertPath certChain) | ||||
|             throws CertificateEncodingException { | ||||
|         return certChain.getEncoded("PKCS7"); | ||||
|     } | ||||
| 
 | ||||
|     public static CertPath getCertificateChain(InputStream is) throws CertificateException, NoSuchProviderException { | ||||
|         CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); | ||||
|     public static CertPath getCertificateChain(InputStream is) | ||||
|             throws CertificateException, NoSuchProviderException { | ||||
|         CertificateFactory cf = | ||||
|                 CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); | ||||
|         return cf.generateCertPath(is, "PKCS7"); | ||||
|     } | ||||
| 
 | ||||
|     public static CertPath getCertificateChain(List<X509Certificate> certs) throws CertificateException, | ||||
|             NoSuchProviderException { | ||||
|         CertificateFactory cf = CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); | ||||
|     public static CertPath getCertificateChain(List<X509Certificate> certs) | ||||
|             throws CertificateException, NoSuchProviderException { | ||||
|         CertificateFactory cf = | ||||
|                 CertificateFactory.getInstance("X.509", BouncyCastleProvider.PROVIDER_NAME); | ||||
|         return cf.generateCertPath(certs); | ||||
|     } | ||||
| 
 | ||||
|     public static X509Certificate getX509CertificateFromPfx(byte[] pfxDER, String passwd) throws Exception { | ||||
|         InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder() | ||||
|             .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(passwd.toCharArray()); | ||||
|     public static X509Certificate getX509CertificateFromPfx(byte[] pfxDER, String passwd) | ||||
|             throws Exception { | ||||
|         InputDecryptorProvider inputDecryptorProvider = | ||||
|                 new JcePKCSPBEInputDecryptorProviderBuilder() | ||||
|                         .setProvider(BouncyCastleProvider.PROVIDER_NAME) | ||||
|                         .build(passwd.toCharArray()); | ||||
|         PKCS12PfxPdu pfx = new PKCS12PfxPdu(pfxDER); | ||||
| 
 | ||||
|         ContentInfo[] infos = pfx.getContentInfos(); | ||||
| @ -126,7 +134,8 @@ public class SM2CertUtil { | ||||
| 
 | ||||
|         for (int i = 0; i != infos.length; i++) { | ||||
|             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(); | ||||
|                 X509CertificateHolder certHoler = (X509CertificateHolder) bags[0].getBagValue(); | ||||
|                 return SM2CertUtil.getX509Certificate(certHoler.getEncoded()); | ||||
| @ -140,9 +149,12 @@ public class SM2CertUtil { | ||||
|         return SM2CertUtil.getBCECPublicKey(getX509CertificateFromPfx(pfxDER, passwd)); | ||||
|     } | ||||
| 
 | ||||
|     public static BCECPrivateKey getPrivateKeyFromPfx(byte[] pfxDER, String passwd) throws Exception { | ||||
|         InputDecryptorProvider inputDecryptorProvider = new JcePKCSPBEInputDecryptorProviderBuilder() | ||||
|             .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(passwd.toCharArray()); | ||||
|     public static BCECPrivateKey getPrivateKeyFromPfx(byte[] pfxDER, String passwd) | ||||
|             throws Exception { | ||||
|         InputDecryptorProvider inputDecryptorProvider = | ||||
|                 new JcePKCSPBEInputDecryptorProviderBuilder() | ||||
|                         .setProvider(BouncyCastleProvider.PROVIDER_NAME) | ||||
|                         .build(passwd.toCharArray()); | ||||
|         PKCS12PfxPdu pfx = new PKCS12PfxPdu(pfxDER); | ||||
| 
 | ||||
|         ContentInfo[] infos = pfx.getContentInfos(); | ||||
| @ -154,7 +166,8 @@ public class SM2CertUtil { | ||||
|             if (!infos[i].getContentType().equals(PKCSObjectIdentifiers.encryptedData)) { | ||||
|                 PKCS12SafeBagFactory dataFact = new PKCS12SafeBagFactory(infos[i]); | ||||
|                 PKCS12SafeBag[] bags = dataFact.getSafeBags(); | ||||
|                 PKCS8EncryptedPrivateKeyInfo encInfo = (PKCS8EncryptedPrivateKeyInfo) bags[0].getBagValue(); | ||||
|                 PKCS8EncryptedPrivateKeyInfo encInfo = | ||||
|                         (PKCS8EncryptedPrivateKeyInfo) bags[0].getBagValue(); | ||||
|                 PrivateKeyInfo info = encInfo.decryptPrivateKeyInfo(inputDecryptorProvider); | ||||
|                 BCECPrivateKey privateKey = BCECUtil.convertPKCS8ToECPrivateKey(info.getEncoded()); | ||||
|                 return privateKey; | ||||
|  | ||||
| @ -21,41 +21,41 @@ public class SM2PfxMaker { | ||||
| 
 | ||||
|     /** | ||||
|      * @param privKey 用户私钥 | ||||
|      * @param pubKey  用户公钥 | ||||
|      * @param chain   X509证书数组,切记这里固定了必须是3个元素的数组,且第一个必须是叶子证书、第二个为中级CA证书、第三个为根CA证书 | ||||
|      * @param passwd  口令 | ||||
|      * @param pubKey 用户公钥 | ||||
|      * @param chain X509证书数组,切记这里固定了必须是3个元素的数组,且第一个必须是叶子证书、第二个为中级CA证书、第三个为根CA证书 | ||||
|      * @param passwd 口令 | ||||
|      * @return | ||||
|      * @throws NoSuchAlgorithmException | ||||
|      * @throws IOException | ||||
|      * @throws PKCSException | ||||
|      */ | ||||
|     public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate[] chain, String passwd) | ||||
|         throws NoSuchAlgorithmException, IOException, PKCSException { | ||||
|     public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate[] chain, | ||||
|             String passwd) throws NoSuchAlgorithmException, IOException, PKCSException { | ||||
|         JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); | ||||
| 
 | ||||
|         PKCS12SafeBagBuilder taCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[2]); | ||||
|         taCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||
|             new DERBMPString("Primary Certificate")); | ||||
|                 new DERBMPString("Primary Certificate")); | ||||
| 
 | ||||
|         PKCS12SafeBagBuilder caCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[1]); | ||||
|         caCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||
|             new DERBMPString("Intermediate Certificate")); | ||||
|                 new DERBMPString("Intermediate Certificate")); | ||||
| 
 | ||||
|         PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(chain[0]); | ||||
|         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||
|             new DERBMPString("User Key")); | ||||
|                 new DERBMPString("User Key")); | ||||
|         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, | ||||
|             extUtils.createSubjectKeyIdentifier(pubKey)); | ||||
|                 extUtils.createSubjectKeyIdentifier(pubKey)); | ||||
| 
 | ||||
|         char[] passwdChars = passwd.toCharArray(); | ||||
|         PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, | ||||
|             new BcPKCS12PBEOutputEncryptorBuilder( | ||||
|                 PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, | ||||
|                 new CBCBlockCipher(new DESedeEngine())).build(passwdChars)); | ||||
|                 new BcPKCS12PBEOutputEncryptorBuilder( | ||||
|                         PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, | ||||
|                         new CBCBlockCipher(new DESedeEngine())).build(passwdChars)); | ||||
|         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||
|             new DERBMPString("User Key")); | ||||
|                 new DERBMPString("User Key")); | ||||
|         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, | ||||
|             extUtils.createSubjectKeyIdentifier(pubKey)); | ||||
|                 extUtils.createSubjectKeyIdentifier(pubKey)); | ||||
| 
 | ||||
|         PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder(); | ||||
|         PKCS12SafeBag[] certs = new PKCS12SafeBag[3]; | ||||
| @ -64,49 +64,47 @@ public class SM2PfxMaker { | ||||
|         certs[2] = taCertBagBuilder.build(); | ||||
|         pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder( | ||||
|                 PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, | ||||
|                 new CBCBlockCipher(new RC2Engine())).build(passwdChars), | ||||
|             certs); | ||||
|                 new CBCBlockCipher(new RC2Engine())).build(passwdChars), certs); | ||||
|         pfxPduBuilder.addData(keyBagBuilder.build()); | ||||
|         return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwdChars); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param privKey 用户私钥 | ||||
|      * @param pubKey  用户公钥 | ||||
|      * @param cert    X509证书 | ||||
|      * @param passwd  口令 | ||||
|      * @param pubKey 用户公钥 | ||||
|      * @param cert X509证书 | ||||
|      * @param passwd 口令 | ||||
|      * @return | ||||
|      * @throws NoSuchAlgorithmException | ||||
|      * @throws IOException | ||||
|      * @throws PKCSException | ||||
|      */ | ||||
|     public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate cert, String passwd) | ||||
|         throws NoSuchAlgorithmException, IOException, PKCSException { | ||||
|     public PKCS12PfxPdu makePfx(PrivateKey privKey, PublicKey pubKey, X509Certificate cert, | ||||
|             String passwd) throws NoSuchAlgorithmException, IOException, PKCSException { | ||||
|         JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); | ||||
| 
 | ||||
|         PKCS12SafeBagBuilder eeCertBagBuilder = new JcaPKCS12SafeBagBuilder(cert); | ||||
|         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||
|             new DERBMPString("User Key")); | ||||
|                 new DERBMPString("User Key")); | ||||
|         eeCertBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, | ||||
|             extUtils.createSubjectKeyIdentifier(pubKey)); | ||||
|                 extUtils.createSubjectKeyIdentifier(pubKey)); | ||||
| 
 | ||||
|         char[] passwdChars = passwd.toCharArray(); | ||||
|         PKCS12SafeBagBuilder keyBagBuilder = new JcaPKCS12SafeBagBuilder(privKey, | ||||
|             new BcPKCS12PBEOutputEncryptorBuilder( | ||||
|                 PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, | ||||
|                 new CBCBlockCipher(new DESedeEngine())).build(passwdChars)); | ||||
|                 new BcPKCS12PBEOutputEncryptorBuilder( | ||||
|                         PKCSObjectIdentifiers.pbeWithSHAAnd3_KeyTripleDES_CBC, | ||||
|                         new CBCBlockCipher(new DESedeEngine())).build(passwdChars)); | ||||
|         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, | ||||
|             new DERBMPString("User Key")); | ||||
|                 new DERBMPString("User Key")); | ||||
|         keyBagBuilder.addBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, | ||||
|             extUtils.createSubjectKeyIdentifier(pubKey)); | ||||
|                 extUtils.createSubjectKeyIdentifier(pubKey)); | ||||
| 
 | ||||
|         PKCS12PfxPduBuilder pfxPduBuilder = new PKCS12PfxPduBuilder(); | ||||
|         PKCS12SafeBag[] certs = new PKCS12SafeBag[1]; | ||||
|         certs[0] = eeCertBagBuilder.build(); | ||||
|         pfxPduBuilder.addEncryptedData(new BcPKCS12PBEOutputEncryptorBuilder( | ||||
|                 PKCSObjectIdentifiers.pbeWithSHAAnd40BitRC2_CBC, | ||||
|                 new CBCBlockCipher(new RC2Engine())).build(passwdChars), | ||||
|             certs); | ||||
|                 new CBCBlockCipher(new RC2Engine())).build(passwdChars), certs); | ||||
|         pfxPduBuilder.addData(keyBagBuilder.build()); | ||||
|         return pfxPduBuilder.build(new BcPKCS12MacCalculatorBuilder(), passwdChars); | ||||
|     } | ||||
|  | ||||
| @ -12,9 +12,8 @@ public class SM2Pkcs12Maker { | ||||
| 
 | ||||
|     /** | ||||
|      * @param privKey 用户私钥 | ||||
|      * @param chain   X509证书数组, | ||||
|      *                第一个(index 0)为privKey对应的证书,index i+1 是index i的CA证书 | ||||
|      * @param passwd  口令 | ||||
|      * @param chain X509证书数组, 第一个(index 0)为privKey对应的证书,index i+1 是index i的CA证书 | ||||
|      * @param passwd 口令 | ||||
|      * @return the PKCS#12 keystore | ||||
|      * @throws NoSuchProviderException | ||||
|      * @throws KeyStoreException | ||||
| @ -24,8 +23,8 @@ public class SM2Pkcs12Maker { | ||||
|      * @throws PKCSException | ||||
|      */ | ||||
|     public KeyStore makePkcs12(PrivateKey privKey, X509Certificate[] chain, char[] passwd) | ||||
|         throws KeyStoreException, NoSuchProviderException, | ||||
|             NoSuchAlgorithmException, CertificateException, IOException { | ||||
|             throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, | ||||
|             CertificateException, IOException { | ||||
|         KeyStore ks = KeyStore.getInstance("PKCS12", "BC"); | ||||
|         ks.load(null, passwd); | ||||
|         ks.setKeyEntry("User Key", privKey, passwd, chain); | ||||
| @ -34,16 +33,16 @@ public class SM2Pkcs12Maker { | ||||
| 
 | ||||
|     /** | ||||
|      * @param privKey 用户私钥 | ||||
|      * @param cert    X509证书 | ||||
|      * @param passwd  口令 | ||||
|      * @param cert X509证书 | ||||
|      * @param passwd 口令 | ||||
|      * @return the PKCS12 keystore | ||||
|      * @throws NoSuchAlgorithmException | ||||
|      * @throws IOException | ||||
|      * @throws PKCSException | ||||
|      */ | ||||
|     public KeyStore makePkcs12(PrivateKey privKey, X509Certificate cert, char[] passwd) | ||||
|         throws KeyStoreException, NoSuchProviderException, | ||||
|             NoSuchAlgorithmException, CertificateException, IOException { | ||||
|       return makePkcs12(privKey, new X509Certificate[] {cert}, passwd); | ||||
|             throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, | ||||
|             CertificateException, IOException { | ||||
|         return makePkcs12(privKey, new X509Certificate[] {cert}, passwd); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -23,7 +23,8 @@ public class SM2PrivateKey extends BCECPrivateKey { | ||||
| 
 | ||||
|     public SM2PrivateKey(BCECPrivateKey privateKey, BCECPublicKey publicKey) { | ||||
|         super(privateKey.getAlgorithm(), privateKey); | ||||
|         this.sm2PublicKey = getSM2PublicKeyDetails(new SM2PublicKey(publicKey.getAlgorithm(), publicKey)); | ||||
|         this.sm2PublicKey = | ||||
|                 getSM2PublicKeyDetails(new SM2PublicKey(publicKey.getAlgorithm(), publicKey)); | ||||
|         this.withCompression = false; | ||||
|     } | ||||
| 
 | ||||
| @ -33,8 +34,8 @@ public class SM2PrivateKey extends BCECPrivateKey { | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Return a PKCS8 representation of the key. The sequence returned | ||||
|      * represents a full PrivateKeyInfo object. | ||||
|      * Return a PKCS8 representation of the key. The sequence returned represents a full | ||||
|      * PrivateKeyInfo object. | ||||
|      * | ||||
|      * @return a PKCS8 representation of the key. | ||||
|      */ | ||||
| @ -48,20 +49,25 @@ public class SM2PrivateKey extends BCECPrivateKey { | ||||
|         if (ecSpec == null) { | ||||
|             orderBitLength = ECUtil.getOrderBitLength(configuration, null, this.getS()); | ||||
|         } else { | ||||
|             orderBitLength = ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS()); | ||||
|             orderBitLength = | ||||
|                     ECUtil.getOrderBitLength(configuration, ecSpec.getOrder(), this.getS()); | ||||
|         } | ||||
| 
 | ||||
|         PrivateKeyInfo info; | ||||
|         org.bouncycastle.asn1.sec.ECPrivateKey keyStructure; | ||||
| 
 | ||||
|         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 { | ||||
|             keyStructure = new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params); | ||||
|             keyStructure = | ||||
|                     new org.bouncycastle.asn1.sec.ECPrivateKey(orderBitLength, this.getS(), params); | ||||
|         } | ||||
| 
 | ||||
|         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); | ||||
|         } catch (IOException e) { | ||||
| @ -71,10 +77,11 @@ public class SM2PrivateKey extends BCECPrivateKey { | ||||
| 
 | ||||
|     private DERBitString getSM2PublicKeyDetails(SM2PublicKey pub) { | ||||
|         try { | ||||
|             SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); | ||||
|             SubjectPublicKeyInfo info = | ||||
|                     SubjectPublicKeyInfo.getInstance(ASN1Primitive.fromByteArray(pub.getEncoded())); | ||||
| 
 | ||||
|             return info.getPublicKeyData(); | ||||
|         } catch (IOException e) {   // should never happen | ||||
|         } catch (IOException e) { // should never happen | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -10,7 +10,8 @@ import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; | ||||
| import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; | ||||
| 
 | ||||
| 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; | ||||
| 
 | ||||
| @ -26,13 +27,13 @@ public class SM2PublicKey extends BCECPublicKey { | ||||
| 
 | ||||
|     @Override | ||||
|     public byte[] getEncoded() { | ||||
|         ASN1OctetString p = ASN1OctetString.getInstance( | ||||
|             new X9ECPoint(getQ(), withCompression).toASN1Primitive()); | ||||
|         ASN1OctetString p = ASN1OctetString | ||||
|                 .getInstance(new X9ECPoint(getQ(), withCompression).toASN1Primitive()); | ||||
| 
 | ||||
|         // stored curve is null if ImplicitlyCa | ||||
|         SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( | ||||
|             new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ID_SM2_PUBKEY_PARAM), | ||||
|             p.getOctets()); | ||||
|                 new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ID_SM2_PUBKEY_PARAM), | ||||
|                 p.getOctets()); | ||||
| 
 | ||||
|         return KeyUtil.getEncodedSubjectPublicKeyInfo(info); | ||||
|     } | ||||
|  | ||||
| @ -28,9 +28,7 @@ import java.util.List; | ||||
| public class SM2X509CertMaker { | ||||
| 
 | ||||
|     private static enum CertLevel { | ||||
|         RootCA, | ||||
|         SubCA, | ||||
|         EndEntity | ||||
|         RootCA, SubCA, EndEntity | ||||
|     } // class CertLevel | ||||
| 
 | ||||
|     public static final String SIGN_ALGO_SM3WITHSM2 = "SM3withSM2"; | ||||
| @ -41,16 +39,14 @@ public class SM2X509CertMaker { | ||||
|     private KeyPair issuerKeyPair; | ||||
| 
 | ||||
|     /** | ||||
|      * @param issuerKeyPair 证书颁发者的密钥对。 | ||||
|      *                      其实一般的CA的私钥都是要严格保护的。 | ||||
|      *                      一般CA的私钥都会放在加密卡/加密机里,证书的签名由加密卡/加密机完成。 | ||||
|      *                      这里仅是为了演示BC库签发证书的用法,所以暂时不作太多要求。 | ||||
|      * @param certExpire    证书有效时间,单位毫秒 | ||||
|      * @param issuer        证书颁发者信息 | ||||
|      * @param snAllocator   维护/分配证书序列号的实例,证书序列号应该递增且不重复 | ||||
|      * @param issuerKeyPair 证书颁发者的密钥对。 其实一般的CA的私钥都是要严格保护的。 一般CA的私钥都会放在加密卡/加密机里,证书的签名由加密卡/加密机完成。 | ||||
|      *        这里仅是为了演示BC库签发证书的用法,所以暂时不作太多要求。 | ||||
|      * @param certExpire 证书有效时间,单位毫秒 | ||||
|      * @param issuer 证书颁发者信息 | ||||
|      * @param snAllocator 维护/分配证书序列号的实例,证书序列号应该递增且不重复 | ||||
|      */ | ||||
|     public SM2X509CertMaker(KeyPair issuerKeyPair, long certExpire, X500Name issuer, | ||||
|                             CertSNAllocator snAllocator) { | ||||
|             CertSNAllocator snAllocator) { | ||||
|         this.issuerKeyPair = issuerKeyPair; | ||||
|         this.certExpire = certExpire; | ||||
|         this.issuerDN = issuer; | ||||
| @ -64,8 +60,7 @@ public class SM2X509CertMaker { | ||||
|      * @return 新的证书 | ||||
|      * @throws Exception 如果错误发生 | ||||
|      */ | ||||
|     public X509Certificate makeRootCACert(byte[] csr) | ||||
|             throws Exception { | ||||
|     public X509Certificate makeRootCACert(byte[] csr) throws Exception { | ||||
|         KeyUsage usage = new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign); | ||||
|         return makeCertificate(CertLevel.RootCA, null, csr, usage, null); | ||||
|     } | ||||
| @ -77,8 +72,7 @@ public class SM2X509CertMaker { | ||||
|      * @return 新的证书 | ||||
|      * @throws Exception 如果错误发生 | ||||
|      */ | ||||
|     public X509Certificate makeSubCACert(byte[] csr) | ||||
|             throws Exception { | ||||
|     public X509Certificate makeSubCACert(byte[] csr) throws Exception { | ||||
|         KeyUsage usage = new KeyUsage(KeyUsage.keyCertSign | KeyUsage.cRLSign); | ||||
|         return makeCertificate(CertLevel.SubCA, 0, csr, usage, null); | ||||
|     } | ||||
| @ -90,10 +84,9 @@ public class SM2X509CertMaker { | ||||
|      * @return 新的证书 | ||||
|      * @throws Exception 如果错误发生 | ||||
|      */ | ||||
|     public X509Certificate makeSSLEndEntityCert(byte[] csr) | ||||
|         throws Exception { | ||||
|     public X509Certificate makeSSLEndEntityCert(byte[] csr) throws Exception { | ||||
|         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 新的证书 | ||||
|      * @throws Exception 如果错误发生 | ||||
|      */ | ||||
|     public X509Certificate makeEndEntityCert(byte[] csr, | ||||
|                                              KeyPurposeId[] extendedKeyUsages) | ||||
|     public X509Certificate makeEndEntityCert(byte[] csr, KeyPurposeId[] extendedKeyUsages) | ||||
|             throws Exception { | ||||
|         KeyUsage usage = new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyAgreement | ||||
|                             | KeyUsage.dataEncipherment | KeyUsage.keyEncipherment); | ||||
|                 | KeyUsage.dataEncipherment | KeyUsage.keyEncipherment); | ||||
|         return makeCertificate(CertLevel.SubCA, null, csr, usage, extendedKeyUsages); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * @param isCA     是否是颁发给CA的证书 | ||||
|      * @param isCA 是否是颁发给CA的证书 | ||||
|      * @param keyUsage 证书用途 | ||||
|      * @param csr      CSR | ||||
|      * @param csr CSR | ||||
|      * @return | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     private X509Certificate makeCertificate(CertLevel certLevel, Integer pathLenConstrain, | ||||
|                                             byte[] csr, KeyUsage keyUsage, KeyPurposeId[] extendedKeyUsages) | ||||
|             throws Exception { | ||||
|             byte[] csr, KeyUsage keyUsage, KeyPurposeId[] extendedKeyUsages) throws Exception { | ||||
|         if (certLevel == CertLevel.EndEntity) { | ||||
|             if (keyUsage.hasUsages(KeyUsage.keyCertSign)) { | ||||
|               throw new IllegalArgumentException( | ||||
|                   "keyusage keyCertSign is not allowed in EndEntity Certificate"); | ||||
|                 throw new IllegalArgumentException( | ||||
|                         "keyusage keyCertSign is not allowed in EndEntity Certificate"); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
| @ -139,13 +130,11 @@ public class SM2X509CertMaker { | ||||
|         String email = null; | ||||
|         String commonName = null; | ||||
|         /* | ||||
|          * RFC 5280 §4.2.1.6 Subject | ||||
|          *  Conforming implementations generating new certificates with | ||||
|          *  electronic mail addresses MUST use the rfc822Name in the subject | ||||
|          *  alternative name extension (Section 4.2.1.6) to describe such | ||||
|          *  identities.  Simultaneous inclusion of the emailAddress attribute in | ||||
|          *  the subject distinguished name to support legacy implementations is | ||||
|          *  deprecated but permitted. | ||||
|          * RFC 5280 §4.2.1.6 Subject Conforming implementations generating new certificates with | ||||
|          * electronic mail addresses MUST use the rfc822Name in the subject alternative name | ||||
|          * extension (Section 4.2.1.6) to describe such identities. Simultaneous inclusion of the | ||||
|          * emailAddress attribute in the subject distinguished name to support legacy | ||||
|          * implementations is deprecated but permitted. | ||||
|          */ | ||||
|         RDN[] rdns = subject.getRDNs(); | ||||
|         List<RDN> newRdns = new ArrayList<>(rdns.length); | ||||
| @ -167,9 +156,8 @@ public class SM2X509CertMaker { | ||||
|         List<GeneralName> subjectAltNames = new LinkedList<>(); | ||||
|         if (email != null) { | ||||
|             subject = new X500Name(newRdns.toArray(new RDN[0])); | ||||
|             subjectAltNames.add( | ||||
|                 new GeneralName(GeneralName.rfc822Name, | ||||
|                     new DERIA5String(email, true))); | ||||
|             subjectAltNames | ||||
|                     .add(new GeneralName(GeneralName.rfc822Name, new DERIA5String(email, true))); | ||||
|         } | ||||
| 
 | ||||
|         boolean selfSignedEECert = false; | ||||
| @ -178,13 +166,14 @@ public class SM2X509CertMaker { | ||||
|                 if (issuerDN.equals(subject)) { | ||||
|                     subject = issuerDN; | ||||
|                 } else { | ||||
|                     throw new IllegalArgumentException("subject != issuer for certLevel " + CertLevel.RootCA); | ||||
|                     throw new IllegalArgumentException( | ||||
|                             "subject != issuer for certLevel " + CertLevel.RootCA); | ||||
|                 } | ||||
|                 break; | ||||
|             case SubCA: | ||||
|                 if (issuerDN.equals(subject)) { | ||||
|                     throw new IllegalArgumentException( | ||||
|                         "subject MUST not equals issuer for certLevel " + certLevel); | ||||
|                             "subject MUST not equals issuer for certLevel " + certLevel); | ||||
|                 } | ||||
|                 break; | ||||
|             default: | ||||
| @ -197,17 +186,16 @@ public class SM2X509CertMaker { | ||||
|         BigInteger serialNumber = snAllocator.nextSerialNumber(); | ||||
|         Date notBefore = new Date(); | ||||
|         Date notAfter = new Date(notBefore.getTime() + certExpire); | ||||
|         X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder( | ||||
|             issuerDN, serialNumber, | ||||
|             notBefore, notAfter, | ||||
|             subject, subPub); | ||||
|         X509v3CertificateBuilder v3CertGen = new X509v3CertificateBuilder(issuerDN, serialNumber, | ||||
|                 notBefore, notAfter, subject, subPub); | ||||
| 
 | ||||
|         JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils(); | ||||
|         v3CertGen.addExtension(Extension.subjectKeyIdentifier, false, | ||||
|             extUtils.createSubjectKeyIdentifier(subPub)); | ||||
|                 extUtils.createSubjectKeyIdentifier(subPub)); | ||||
|         if (certLevel != CertLevel.RootCA && !selfSignedEECert) { | ||||
|             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: | ||||
| @ -219,12 +207,13 @@ public class SM2X509CertMaker { | ||||
|         if (certLevel == CertLevel.EndEntity) { | ||||
|             basicConstraints = new BasicConstraints(false); | ||||
|         } else { | ||||
|             basicConstraints = pathLenConstrain == null | ||||
|                 ? new BasicConstraints(true) : new BasicConstraints(pathLenConstrain.intValue()); | ||||
|             basicConstraints = pathLenConstrain == null ? new BasicConstraints(true) | ||||
|                     : new BasicConstraints(pathLenConstrain.intValue()); | ||||
|         } | ||||
|         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); | ||||
| 
 | ||||
|         if (extendedKeyUsages != null) { | ||||
| @ -243,20 +232,21 @@ public class SM2X509CertMaker { | ||||
|                 if (commonName == null) { | ||||
|                     throw new IllegalArgumentException("commonName must not be null"); | ||||
|                 } | ||||
|                 GeneralName name = new GeneralName(GeneralName.dNSName, | ||||
|                                       new DERIA5String(commonName, true)); | ||||
|                 GeneralName name = | ||||
|                         new GeneralName(GeneralName.dNSName, new DERIA5String(commonName, true)); | ||||
|                 subjectAltNames.add(name); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (!subjectAltNames.isEmpty()) { | ||||
|             v3CertGen.addExtension(Extension.subjectAlternativeName, false, | ||||
|                 new GeneralNames(subjectAltNames.toArray(new GeneralName[0]))); | ||||
|                     new GeneralNames(subjectAltNames.toArray(new GeneralName[0]))); | ||||
|         } | ||||
| 
 | ||||
|         JcaContentSignerBuilder contentSignerBuilder = makeContentSignerBuilder(issPub); | ||||
|         X509Certificate cert = new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME) | ||||
|             .getCertificate(v3CertGen.build(contentSignerBuilder.build(issPriv))); | ||||
|         X509Certificate cert = | ||||
|                 new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME) | ||||
|                         .getCertificate(v3CertGen.build(contentSignerBuilder.build(issPriv))); | ||||
|         cert.verify(issPub); | ||||
| 
 | ||||
|         return cert; | ||||
| @ -264,7 +254,8 @@ public class SM2X509CertMaker { | ||||
| 
 | ||||
|     private JcaContentSignerBuilder makeContentSignerBuilder(PublicKey issPub) throws Exception { | ||||
|         if (issPub.getAlgorithm().equals("EC")) { | ||||
|             JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder(SIGN_ALGO_SM3WITHSM2); | ||||
|             JcaContentSignerBuilder contentSignerBuilder = | ||||
|                     new JcaContentSignerBuilder(SIGN_ALGO_SM3WITHSM2); | ||||
|             contentSignerBuilder.setProvider(BouncyCastleProvider.PROVIDER_NAME); | ||||
|             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]; | ||||
|         System.arraycopy(nLenBytes, 0, data, 0, nLenBytes.length); | ||||
|         System.arraycopy(nBytes, 0, data, nLenBytes.length, nBytes.length); | ||||
|         System.arraycopy( | ||||
|                 cipherBytes, 0, data, nLenBytes.length + nBytes.length, cipherBytes.length); | ||||
|         System.arraycopy(cipherBytes, 0, data, nLenBytes.length + nBytes.length, | ||||
|                 cipherBytes.length); | ||||
|         return data; | ||||
|     } | ||||
| 
 | ||||
| @ -49,11 +49,8 @@ public class PaillierCipher { | ||||
|     public static BigInteger decrypt(byte[] ciphertext, PrivateKey privateKey) { | ||||
|         RSAPrivateCrtKey rsaPriKey = (RSAPrivateCrtKey) privateKey; | ||||
|         BigInteger n = rsaPriKey.getModulus(); | ||||
|         BigInteger lambda = | ||||
|                 rsaPriKey | ||||
|                         .getPrimeP() | ||||
|                         .subtract(BigInteger.ONE) | ||||
|                         .multiply(rsaPriKey.getPrimeQ().subtract(BigInteger.ONE)); | ||||
|         BigInteger lambda = rsaPriKey.getPrimeP().subtract(BigInteger.ONE) | ||||
|                 .multiply(rsaPriKey.getPrimeQ().subtract(BigInteger.ONE)); | ||||
| 
 | ||||
|         int nLen = CommonUtils.byte2ToUnsignedShort(ciphertext); | ||||
|         byte[] nBytes = new byte[nLen]; | ||||
| @ -70,13 +67,8 @@ public class PaillierCipher { | ||||
| 
 | ||||
|         BigInteger mu = lambda.modInverse(n); | ||||
|         BigInteger nsquare = n.multiply(n); | ||||
|         BigInteger message = | ||||
|                 intCiphertext | ||||
|                         .modPow(lambda, nsquare) | ||||
|                         .subtract(BigInteger.ONE) | ||||
|                         .divide(n) | ||||
|                         .multiply(mu) | ||||
|                         .mod(n); | ||||
|         BigInteger message = intCiphertext.modPow(lambda, nsquare).subtract(BigInteger.ONE) | ||||
|                 .divide(n).multiply(mu).mod(n); | ||||
|         BigInteger maxValue = BigInteger.ONE.shiftLeft(n.bitLength() / 2); | ||||
|         if (message.compareTo(maxValue) > 0) { | ||||
|             return message.subtract(n); | ||||
| @ -86,10 +78,8 @@ public class PaillierCipher { | ||||
|     } | ||||
| 
 | ||||
|     public static String ciphertextAdd(String ciphertext1, String ciphertext2) { | ||||
|         return CommonUtils.byteToHexString( | ||||
|                 ciphertextAdd( | ||||
|                         CommonUtils.hexStringToBytes(ciphertext1), | ||||
|                         CommonUtils.hexStringToBytes(ciphertext2))); | ||||
|         return CommonUtils.byteToHexString(ciphertextAdd(CommonUtils.hexStringToBytes(ciphertext1), | ||||
|                 CommonUtils.hexStringToBytes(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]; | ||||
|         System.arraycopy(nLenBytes, 0, data, 0, nLenBytes.length); | ||||
|         System.arraycopy(nBytes1, 0, data, nLenBytes.length, nBytes1.length); | ||||
|         System.arraycopy( | ||||
|                 cipherBytes, 0, data, nLenBytes.length + nBytes1.length, cipherBytes.length); | ||||
|         System.arraycopy(cipherBytes, 0, data, nLenBytes.length + nBytes1.length, | ||||
|                 cipherBytes.length); | ||||
|         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.Test; | ||||
| import org.paillier.PaillierCipher; | ||||
| import org.paillier.PaillierKeyPair; | ||||
| 
 | ||||
| import java.math.BigInteger; | ||||
| import java.security.KeyPair; | ||||
| @ -18,7 +16,7 @@ public class PaillierTest { | ||||
|         KeyPair keypair = PaillierKeyPair.generateGoodKeyPair(); | ||||
|         RSAPublicKey pubKey = (RSAPublicKey) keypair.getPublic(); | ||||
|         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 privateKeyStr = PaillierKeyPair.privateKeyToPem(priKey); | ||||
| @ -62,35 +60,33 @@ public class PaillierTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void decryptTest() { | ||||
|         String privateKeyStr = | ||||
|                 "-----BEGIN PRIVATE KEY-----\n" | ||||
|                         + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1f/Oa//I+SFNN\n" | ||||
|                         + "v+PmHGJ1vLGFDu6A0IQV9DcX/hf2R2JFW/ONxfjlrtAh4dW7itMwIA6u64UlKiml\n" | ||||
|                         + "4UuVBT9ca4wv7R87DFqhxquh+ObMzo2x6QAaXnvL5WMmu8+/aLg6Nc06BXtJHsiw\n" | ||||
|                         + "TO7B09AcDNccdDyI+gXP4LEsIoh9HR1p41cq1RKe5c9khLryc5zQqf6NWlw4aWr9\n" | ||||
|                         + "AI5w4m7zhsTiDH1R9qLSJugOltY+9hLF7E9LexMLwXoQUYyi0WGxRe0h03+EQszv\n" | ||||
|                         + "4gQA4paJPAnk8k6VrUyTlBdeoYneInxZ0FEtFffk/rqVt4B80jjVRTbleSmDNvb7\n" | ||||
|                         + "KFp+KHSrAgMBAAECggEAG0jM2jQ3ul0tCLccD2+c7Y4cMaB5AixWbuZzkcvE1mUM\n" | ||||
|                         + "xNh52Io2THDnIPDOLI9GCCoJiwokzd10vVcNAa30RHR2co327+1/gmpXStYb/BXg\n" | ||||
|                         + "/ynDtjMV8STeruf05xVa/IUyANLqIafbC4XFLqYk1tKnU8O1hfHwBbwFZlkao5QH\n" | ||||
|                         + "IN9CyDIsyyv30JbHz47HJePZkTm/2iOq4ru+pKYFHeDz4EIEJRGl8HD7wtpo3F5E\n" | ||||
|                         + "mxe9uI5GMCdbswGnmw1a0u/VrSXpxwVyQMGHP6KWZ0dIunFW0Sh4DEdf9/tygtwx\n" | ||||
|                         + "nJ+/RYGqTKLv59+OkJGH/e6J6BV9rKYfjTiRC+hAAQKBgQD/1dW9WSXnquVGdJkq\n" | ||||
|                         + "QnohnMp/EkaXA3e3RiS9Bx9hhNwfdijqx3zyV1LnHGhuEaCXSCoy6zIOLQxOkkA8\n" | ||||
|                         + "rLCzpN/hp3c8pQUwYlQodZ+G/0272jCsD2vmdOuRP2WuFA9hqGgFvUbXkXh4mcEB\n" | ||||
|                         + "xKJY/jAddZvmnvs/dcLt6oJMqwKBgQC1nd18hcjQmIRARRUGs1ZU75yTaLKp+lXf\n" | ||||
|                         + "M7lg8RKE9sWf4ZoT3Snj+pimUOqliE10LiHruawa137q/UC+iI0/I4H9AUhv2mAw\n" | ||||
|                         + "m5drd+G4s6uTiCf7OQxBTmGHEvv5xH7gQih6sjOJI+N57xanC1XMGxijMOSy/D+O\n" | ||||
|                         + "sLxB8yJ4AQKBgQDYYX3kJnB+3vYIfznEmnE92KUUkNqPg2lP483S6yFJk9ux6Hh3\n" | ||||
|                         + "Cr7NIbqGqmpRHiubiHfYlUDC6KsOEXivWMgjSQHqk3+wFUqsP546kjGZNnoCtmqQ\n" | ||||
|                         + "PILgameLc/mGIIVZ7dv9brdqQCmKp1CtNCiz6Fm9sOlpR3HtnKaAH+aQ/QKBgFVW\n" | ||||
|                         + "37tidfEmqYY1r+KdJGT2zqEpokJi4jTmbiZSQPx/pG8zKB5LXyLEHzSPcyLjQFnm\n" | ||||
|                         + "T4Qfk/Js7jNnWyPssEpJ2gvTrYD5oRdWFTmndEZBDs9dPEQ9Ezggp40763D61w9z\n" | ||||
|                         + "pue4kqTPW1Vxdjh6CA/Hb7VHBT/hbdAT1fI7WCgBAoGAZq1rFESL3roi8DtOWl51\n" | ||||
|                         + "nduNO20Yloe6tlhUAKo63krRHKBeKTyLXycpZHcq6UEfys3dixFfu0lN6002lUku\n" | ||||
|                         + "MTbmNOJWhOCa2xuZY0CeINKFnKBnbiauBpo6x+2J0PoWFn8wd1tzFJPbodk8Km1f\n" | ||||
|                         + "qySov+6mrQxHojQYBu9/yYQ=\n" | ||||
|                         + "-----END PRIVATE KEY-----"; | ||||
|         String privateKeyStr = "-----BEGIN PRIVATE KEY-----\n" | ||||
|                 + "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC1f/Oa//I+SFNN\n" | ||||
|                 + "v+PmHGJ1vLGFDu6A0IQV9DcX/hf2R2JFW/ONxfjlrtAh4dW7itMwIA6u64UlKiml\n" | ||||
|                 + "4UuVBT9ca4wv7R87DFqhxquh+ObMzo2x6QAaXnvL5WMmu8+/aLg6Nc06BXtJHsiw\n" | ||||
|                 + "TO7B09AcDNccdDyI+gXP4LEsIoh9HR1p41cq1RKe5c9khLryc5zQqf6NWlw4aWr9\n" | ||||
|                 + "AI5w4m7zhsTiDH1R9qLSJugOltY+9hLF7E9LexMLwXoQUYyi0WGxRe0h03+EQszv\n" | ||||
|                 + "4gQA4paJPAnk8k6VrUyTlBdeoYneInxZ0FEtFffk/rqVt4B80jjVRTbleSmDNvb7\n" | ||||
|                 + "KFp+KHSrAgMBAAECggEAG0jM2jQ3ul0tCLccD2+c7Y4cMaB5AixWbuZzkcvE1mUM\n" | ||||
|                 + "xNh52Io2THDnIPDOLI9GCCoJiwokzd10vVcNAa30RHR2co327+1/gmpXStYb/BXg\n" | ||||
|                 + "/ynDtjMV8STeruf05xVa/IUyANLqIafbC4XFLqYk1tKnU8O1hfHwBbwFZlkao5QH\n" | ||||
|                 + "IN9CyDIsyyv30JbHz47HJePZkTm/2iOq4ru+pKYFHeDz4EIEJRGl8HD7wtpo3F5E\n" | ||||
|                 + "mxe9uI5GMCdbswGnmw1a0u/VrSXpxwVyQMGHP6KWZ0dIunFW0Sh4DEdf9/tygtwx\n" | ||||
|                 + "nJ+/RYGqTKLv59+OkJGH/e6J6BV9rKYfjTiRC+hAAQKBgQD/1dW9WSXnquVGdJkq\n" | ||||
|                 + "QnohnMp/EkaXA3e3RiS9Bx9hhNwfdijqx3zyV1LnHGhuEaCXSCoy6zIOLQxOkkA8\n" | ||||
|                 + "rLCzpN/hp3c8pQUwYlQodZ+G/0272jCsD2vmdOuRP2WuFA9hqGgFvUbXkXh4mcEB\n" | ||||
|                 + "xKJY/jAddZvmnvs/dcLt6oJMqwKBgQC1nd18hcjQmIRARRUGs1ZU75yTaLKp+lXf\n" | ||||
|                 + "M7lg8RKE9sWf4ZoT3Snj+pimUOqliE10LiHruawa137q/UC+iI0/I4H9AUhv2mAw\n" | ||||
|                 + "m5drd+G4s6uTiCf7OQxBTmGHEvv5xH7gQih6sjOJI+N57xanC1XMGxijMOSy/D+O\n" | ||||
|                 + "sLxB8yJ4AQKBgQDYYX3kJnB+3vYIfznEmnE92KUUkNqPg2lP483S6yFJk9ux6Hh3\n" | ||||
|                 + "Cr7NIbqGqmpRHiubiHfYlUDC6KsOEXivWMgjSQHqk3+wFUqsP546kjGZNnoCtmqQ\n" | ||||
|                 + "PILgameLc/mGIIVZ7dv9brdqQCmKp1CtNCiz6Fm9sOlpR3HtnKaAH+aQ/QKBgFVW\n" | ||||
|                 + "37tidfEmqYY1r+KdJGT2zqEpokJi4jTmbiZSQPx/pG8zKB5LXyLEHzSPcyLjQFnm\n" | ||||
|                 + "T4Qfk/Js7jNnWyPssEpJ2gvTrYD5oRdWFTmndEZBDs9dPEQ9Ezggp40763D61w9z\n" | ||||
|                 + "pue4kqTPW1Vxdjh6CA/Hb7VHBT/hbdAT1fI7WCgBAoGAZq1rFESL3roi8DtOWl51\n" | ||||
|                 + "nduNO20Yloe6tlhUAKo63krRHKBeKTyLXycpZHcq6UEfys3dixFfu0lN6002lUku\n" | ||||
|                 + "MTbmNOJWhOCa2xuZY0CeINKFnKBnbiauBpo6x+2J0PoWFn8wd1tzFJPbodk8Km1f\n" | ||||
|                 + "qySov+6mrQxHojQYBu9/yYQ=\n" + "-----END PRIVATE KEY-----"; | ||||
| 
 | ||||
|         String cipher = | ||||
|                 "0100B57FF39AFFF23E48534DBFE3E61C6275BCB1850EEE80D08415F43717FE17F64762455BF38DC5F8E5AED021E1D5BB8AD330200EAEEB85252A29A5E14B95053F5C6B8C2FED1F3B0C5AA1C6ABA1F8E6CCCE8DB1E9001A5E7BCBE56326BBCFBF68B83A35CD3A057B491EC8B04CEEC1D3D01C0CD71C743C88FA05CFE0B12C22887D1D1D69E3572AD5129EE5CF6484BAF2739CD0A9FE8D5A5C38696AFD008E70E26EF386C4E20C7D51F6A2D226E80E96D63EF612C5EC4F4B7B130BC17A10518CA2D161B145ED21D37F8442CCEFE20400E296893C09E4F24E95AD4C9394175EA189DE227C59D0512D15F7E4FEBA95B7807CD238D54536E579298336F6FB285A7E2874AB6914BF4FF089BFD98EC18D9E8B3D7FB2F5CFC20715C62D34F08E36D84F2CDABA2D1A1798C95161B7831167ED27E8894F1EB25D4E74DF382BF276D9ACBEADB56795F3DF8A4E6CE9DF7B6CFEFD5C66F0BC45D24CCC8E8095A7BF5CE69FEC5579B874A4C9B7C8F13126EC59D7C6DF0404816F638C7D4A84FE038E6F00B5667AC88E4307990E4C06B3864D86B7349275B20A3FB50FBA64706F214CC642219DCEF4453C30B89790F6FB1566A5D557AD7EC5890CA50E80111319F9742943FBD675D18753E5ABD21941832A11332ED902C334309E3770512AC042E1556C3F0ECCFC056C66D7362BA4E7896EA0807412817C68D7B5434AFA0D95A12B950573994F081F996545B871E485C392288E2D61C3B0CBB9FC4E68C1C558A598B03BACFF27967BE8AEA8F1322EC3E0957A3ED84810164A59BDEE2D1514EA68228CB96B59D8BA1E9234A24D57E5F8D7E55724EF0AE9D83F6E2A84B9A1E47B59091201B1B65542BBBB5A988CBBD5395335C4DF821ACEF289D20444B74CABC406A7C4F810EFF85838994DBDD38EDF74D4821153A5128AB98C15409C73891415B194803B3ABF761CEE57D1F58813A7125260E58864970CA2650E0D46C239ED92FCC3491C5FA372838B475D14E4946FCC3C421A76C434C5310D1A17A744551CFB5F99547BB216AD7C1ADA5C27CA64B34C29152D29B0A4B90B0C72A7A18BD19CF278B6F39186A39F91FB4D"; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user