Browse Source

add CSRBuilder and its junitTest

tags/1.0.0
zhanglin33 6 years ago
parent
commit
7b0cc1cafb
3 changed files with 195 additions and 142 deletions
  1. +1
    -1
      source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/RSAUtils.java
  2. +109
    -12
      source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CSRBuilder.java
  3. +85
    -129
      source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CSRBuilderTest.java

+ 1
- 1
source/crypto/crypto-classic/src/main/java/com/jd/blockchain/crypto/utils/classic/RSAUtils.java View File

@@ -83,7 +83,7 @@ public class RSAUtils {
* @return key pair * @return key pair
*/ */
public static AsymmetricCipherKeyPair generateKeyPair_shortExp(){ public static AsymmetricCipherKeyPair generateKeyPair_shortExp(){
return generateKeyPair(new SecureRandom());
return generateKeyPair_shortExp(new SecureRandom());
} }


public static AsymmetricCipherKeyPair generateKeyPair_shortExp(SecureRandom random){ public static AsymmetricCipherKeyPair generateKeyPair_shortExp(SecureRandom random){


+ 109
- 12
source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CSRBuilder.java View File

@@ -1,6 +1,25 @@
package com.jd.blockchain.crypto; package com.jd.blockchain.crypto;


import com.jd.blockchain.crypto.utils.classic.RSAUtils;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStrictStyle;
import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECNamedCurveGenParameterSpec;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
import org.bouncycastle.util.encoders.Base64;


import java.io.IOException;
import java.security.*;


/** /**
* @author zhanglin33 * @author zhanglin33
@@ -10,20 +29,98 @@ import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
*/ */
public class CSRBuilder { public class CSRBuilder {


private String C;
private String ST;
private String L;
private String O;
private String OU;
private String CN;
private String E;
private String BC = BouncyCastleProvider.PROVIDER_NAME;

private PublicKey pubKey;
private PrivateKey privKey;

private String algoName;

public void init() {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
algoName = "SHA1withRSA";
KeyPairGenerator generator;
try {
generator = KeyPairGenerator.getInstance("RSA", BC);
generator.initialize(2048);
KeyPair keyPair = generator.generateKeyPair();
pubKey = keyPair.getPublic();
privKey = keyPair.getPrivate();
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e);
}
}

public void init(String algoName, int KeyLength) {

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
this.algoName = algoName;

KeyPairGenerator generator;
KeyPair keyPair;
String[] hashAndSignature = algoName.split("with");

try {
switch (hashAndSignature[1]) {
case "RSA": {
generator = KeyPairGenerator.getInstance("RSA", BC);
generator.initialize(KeyLength);
keyPair = generator.generateKeyPair();
pubKey = keyPair.getPublic();
privKey = keyPair.getPrivate();
}

case "SM2": {
generator = KeyPairGenerator.getInstance("EC", BC);
generator.initialize(new ECNamedCurveGenParameterSpec("sm2p256v1"));
keyPair = generator.generateKeyPair();
pubKey = keyPair.getPublic();
privKey = keyPair.getPrivate();
}

default: throw new CryptoException("Unsupported key algorithm[" + algoName + "] in CSR!");
}
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
throw new com.jd.blockchain.crypto.CryptoException(e.getMessage(), e);
}
}

public String buildRequest(String countryName, String stateName, String cityName,
String organizationName, String departmentName, String domainName,
String emailName) {

String result = null;
X500NameBuilder nameBuilder = new X500NameBuilder(BCStrictStyle.INSTANCE);

nameBuilder.addRDN(BCStyle.C, countryName); // a country name, and China is short as CN
nameBuilder.addRDN(BCStyle.ST, stateName); // a state or province name
nameBuilder.addRDN(BCStyle.L, cityName); // a city name
nameBuilder.addRDN(BCStyle.O, organizationName); // an organization or corporation name
nameBuilder.addRDN(BCStyle.OU, departmentName); // a division of your organization name
nameBuilder.addRDN(BCStyle.CN, domainName); // a fully qualified domain name
nameBuilder.addRDN(BCStyle.E, emailName); // an email address

try {
X500Name x500Name = nameBuilder.build();

PKCS10CertificationRequestBuilder requestBuilder
= new JcaPKCS10CertificationRequestBuilder(x500Name, pubKey);
PKCS10CertificationRequest request
= requestBuilder.build(new JcaContentSignerBuilder(algoName).setProvider(BC).build(privKey));
byte[] csrBytes = request.getEncoded();
result = Base64.toBase64String(csrBytes);
} catch (OperatorCreationException | IOException e) {
e.printStackTrace();
}

return result;
}


public AsymmetricCipherKeyPair init() {
return null;
public PublicKey getPubKey() {
return pubKey;
} }


public String buildRequest(String keyName, AsymmetricCipherKeyPair keyPair, String algoName,
String[] applicantInfo) {
return null;
public PrivateKey getPrivKey() {
return privKey;
} }
} }

+ 85
- 129
source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CSRBuilderTest.java View File

@@ -1,32 +1,18 @@
package com.jd.blockchain.crypto; package com.jd.blockchain.crypto;


import com.jd.blockchain.crypto.utils.classic.RSAUtils;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x500.X500NameBuilder;
import org.bouncycastle.asn1.x500.style.BCStrictStyle;
import org.bouncycastle.asn1.ASN1Encoding;
import org.bouncycastle.asn1.DERSet;
import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
import org.bouncycastle.asn1.x500.RDN;
import org.bouncycastle.asn1.x500.style.BCStyle; import org.bouncycastle.asn1.x500.style.BCStyle;
import org.bouncycastle.asn1.x500.style.RFC4519Style;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.jcajce.provider.asymmetric.rsa.BCRSAPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest; import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest;
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.encoders.Base64; import org.bouncycastle.util.encoders.Base64;
import org.junit.Test; import org.junit.Test;
import sun.security.rsa.RSAPublicKeyImpl;


import java.io.IOException; import java.io.IOException;
import java.security.*; import java.security.*;


import static org.junit.Assert.fail;
import static org.junit.Assert.*;


/** /**
* @author zhanglin33 * @author zhanglin33
@@ -35,127 +21,97 @@ import static org.junit.Assert.fail;
* @date 2019-05-10, 17:22 * @date 2019-05-10, 17:22
*/ */
public class CSRBuilderTest { public class CSRBuilderTest {
public static String genCSR(String subject, String alg, String provider) {
String signalg = "";
int alglength = 0;
String keyAlg = "";
if (alg.toUpperCase().equals("RSA1024")) {
signalg = "SHA1WithRSA";
alglength = 1024;
keyAlg = "RSA";
} else if (alg.toUpperCase().equals("RSA2048")) {
signalg = "SHA1WithRSA";
alglength = 2048;
keyAlg = "RSA";
} else if (alg.toUpperCase().equals("SM2")) {
signalg = "SM3withSM2";
alglength = 256;
keyAlg = "SM2";
}
KeyPairGenerator keyGen;
PKCS10CertificationRequestBuilder builder;

try {
keyGen = KeyPairGenerator.getInstance(keyAlg);
keyGen.initialize(alglength);
KeyPair kp = keyGen.generateKeyPair();


builder = new PKCS10CertificationRequestBuilder(new X500Name(subject), SubjectPublicKeyInfo.getInstance(kp.getPublic().getEncoded()));
JcaContentSignerBuilder jcaContentSignerBuilder = new JcaContentSignerBuilder(signalg);
jcaContentSignerBuilder.setProvider(provider);
ContentSigner contentSigner = jcaContentSignerBuilder.build(kp.getPrivate());
builder.build(contentSigner);
return builder.toString();
} catch (OperatorCreationException | NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}

@Test
public void csrTest() throws Exception{

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());


String keyName = "RSA";
String sigName = "SHA1withRSA";

String BC = BouncyCastleProvider.PROVIDER_NAME;
KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, BC);

kpg.initialize(2048);

KeyPair kp = kpg.generateKeyPair();
// AsymmetricCipherKeyPair keyPair = RSAUtils.generateKeyPair();


X500NameBuilder builder = new X500NameBuilder(BCStrictStyle.INSTANCE);

builder.addRDN(BCStyle.C,"CN"); // a country name, and China is short as CN
builder.addRDN(BCStyle.ST, "Beijing"); // a state or province name
builder.addRDN(BCStyle.L, "Beijing"); // a city name
builder.addRDN(BCStyle.O, "JD.com"); // an organization or corporation name
builder.addRDN(BCStyle.OU, "Blockchain Department"); // a division of your organization name
builder.addRDN(BCStyle.CN, "ledger.jd.com"); // a fully qualified domain name
builder.addRDN(BCStyle.EmailAddress, "zhanglin33@jd.com"); // an email address

X500Name x500Name = builder.build();

PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(x500Name, kp.getPublic());

// PKCS10CertificationRequest req = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(sigName).build(kp.getPrivate()));
PKCS10CertificationRequest req = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(BC).build(kp.getPrivate()));


byte[] csrBytes = req.getEncoded();
String result = Base64.toBase64String(csrBytes);
System.out.println(result);

}


@Test @Test
public void csr2Test() throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
generationTest(512, "RSA", "SHA1withRSA", "BC");
}

private void generationTest(int keySize, String keyName, String sigName, String provider)
throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyName, "BC");

kpg.initialize(keySize);

KeyPair kp = kpg.generateKeyPair();
public void defaultCSRTest(){


String countryName = "CN";
String stateName = "Beijing";
String cityName = "Beijing";
String organizationName = "JD.com";
String departmentName = "Blockchain Department";
String domainName = "ledger.jd.com";
String emailName = "zhanglin33@jd.com";


X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE);
CSRBuilder builder = new CSRBuilder();


x500NameBld.addRDN(BCStyle.C, "AU");
x500NameBld.addRDN(BCStyle.O, "The Legion of the Bouncy Castle");
x500NameBld.addRDN(BCStyle.L, "Melbourne");
x500NameBld.addRDN(BCStyle.ST, "Victoria");
builder.init();
String csr = builder.buildRequest(countryName,stateName,cityName,
organizationName,departmentName,domainName,
emailName);
System.out.println(csr);


x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org");
PublicKey pubKey = builder.getPubKey();
PrivateKey privKey = builder.getPrivKey();


X500Name subject = x500NameBld.build();

PKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(subject, kp.getPublic());
BCRSAPublicKey pubKey = (BCRSAPublicKey) kp.getPublic();
System.out.println(pubKey.getModulus().bitLength());

PKCS10CertificationRequest req1 = requestBuilder.build(new JcaContentSignerBuilder(sigName).setProvider(provider).build(kp.getPrivate()));

JcaPKCS10CertificationRequest req2 = new JcaPKCS10CertificationRequest(req1.getEncoded()).setProvider(provider);
byte[] crsBytes = Base64.decode(csr);
PKCS10CertificationRequest request = null;
try {
request = new PKCS10CertificationRequest(crsBytes);
} catch (IOException e) {
e.printStackTrace();
}
assertNotNull(request);
assertEquals("1.2.840.113549.1.1.5",request.getSignatureAlgorithm().getAlgorithm().getId());
byte[] pubKeyBytes = new byte[0];
try {
pubKeyBytes = request.getSubjectPublicKeyInfo().getEncoded();
} catch (IOException e) {
e.printStackTrace();
}
assertArrayEquals(pubKeyBytes,pubKey.getEncoded());

RDN[] rdns = request.getSubject().getRDNs();
assertEquals(BCStyle.C, rdns[0].getFirst().getType().toASN1Primitive());
assertEquals(BCStyle.ST, rdns[1].getFirst().getType().toASN1Primitive());
assertEquals(BCStyle.L, rdns[2].getFirst().getType().toASN1Primitive());
assertEquals(BCStyle.O, rdns[3].getFirst().getType().toASN1Primitive());
assertEquals(BCStyle.OU, rdns[4].getFirst().getType().toASN1Primitive());
assertEquals(BCStyle.CN, rdns[5].getFirst().getType().toASN1Primitive());
assertEquals(BCStyle.E, rdns[6].getFirst().getType().toASN1Primitive());

assertEquals("CN", rdns[0].getFirst().getValue().toASN1Primitive().toString());
assertEquals("Beijing", rdns[1].getFirst().getValue().toASN1Primitive().toString());
assertEquals("Beijing", rdns[2].getFirst().getValue().toASN1Primitive().toString());
assertEquals("JD.com", rdns[3].getFirst().getValue().toASN1Primitive().toString());
assertEquals("Blockchain Department", rdns[4].getFirst().getValue().toASN1Primitive().toString());
assertEquals("ledger.jd.com", rdns[5].getFirst().getValue().toASN1Primitive().toString());
assertEquals("zhanglin33@jd.com", rdns[6].getFirst().getValue().toASN1Primitive().toString());

byte[] signature = request.getSignature();

CertificationRequestInfo requestInfo = new CertificationRequestInfo(request.getSubject(),request.getSubjectPublicKeyInfo(),new DERSet());
byte[] message = new byte[0];
try {
message = requestInfo.getEncoded(ASN1Encoding.DER);
} catch (IOException e) {
e.printStackTrace();
}


if (!req2.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(provider).build(kp.getPublic()))) {
fail(sigName + ": Failed verify check.");
Signature signer;
byte[] result = new byte[0];
try {
signer = Signature.getInstance("SHA1withRSA");
signer.initSign(privKey);
signer.update(message);
result = signer.sign();
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
e.printStackTrace();
} }
assertArrayEquals(result,signature);


if (!Arrays.areEqual(req2.getPublicKey().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded())) {
fail(keyName + ": Failed public key check.");
Signature verifier;
boolean isValid = false;
try {
verifier = Signature.getInstance("SHA1withRSA");
verifier.initVerify(pubKey);
verifier.update(message);
isValid = verifier.verify(signature);
} catch (NoSuchAlgorithmException | InvalidKeyException | SignatureException e) {
e.printStackTrace();
} }
assertTrue(isValid);
} }


} }

Loading…
Cancel
Save