From be4f605174e317a3b736dad1f5786b78557a5875 Mon Sep 17 00:00:00 2001 From: zhanglin33 Date: Mon, 13 May 2019 10:12:50 +0800 Subject: [PATCH] add pki --- source/crypto/crypto-adv/pom.xml | 7 + source/crypto/crypto-classic/pom.xml | 6 + .../crypto/utils/classic/CSRTest.java | 58 +++++ .../crypto/utils/classic/CertTest.java | 81 +++++++ .../crypto/utils/classic/RSAUtilsTest.java | 19 +- .../crypto/utils/classic/SSHKeyUtilsTest.java | 212 ++++++++++++++++++ source/crypto/crypto-pki/pom.xml | 34 +++ .../com/jd/blockchain/crypto/CSRBuilder.java | 10 + .../com/jd/blockchain/crypto/CertParser.java | 10 + .../jd/blockchain/crypto/CSRBuilderTest.java | 161 +++++++++++++ .../jd/blockchain/crypto/CertParserTest.java | 10 + source/crypto/pom.xml | 1 + source/pom.xml | 6 + 13 files changed, 614 insertions(+), 1 deletion(-) create mode 100644 source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/CSRTest.java create mode 100644 source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/CertTest.java create mode 100644 source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/SSHKeyUtilsTest.java create mode 100644 source/crypto/crypto-pki/pom.xml create mode 100644 source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CSRBuilder.java create mode 100644 source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CertParser.java create mode 100644 source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CSRBuilderTest.java create mode 100644 source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CertParserTest.java diff --git a/source/crypto/crypto-adv/pom.xml b/source/crypto/crypto-adv/pom.xml index bf759175..6c3705f2 100644 --- a/source/crypto/crypto-adv/pom.xml +++ b/source/crypto/crypto-adv/pom.xml @@ -21,6 +21,13 @@ org.bouncycastle bcprov-jdk15on + + + org.bouncycastle + bcpkix-jdk15on + 1.61 + + com.jd.blockchain binary-proto diff --git a/source/crypto/crypto-classic/pom.xml b/source/crypto/crypto-classic/pom.xml index bd59aeb8..75ab597b 100644 --- a/source/crypto/crypto-classic/pom.xml +++ b/source/crypto/crypto-classic/pom.xml @@ -15,6 +15,12 @@ crypto-framework ${project.version} + + + org.bouncycastle + bcpkix-jdk15on + 1.61 + \ No newline at end of file diff --git a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/CSRTest.java b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/CSRTest.java new file mode 100644 index 00000000..ec28db62 --- /dev/null +++ b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/CSRTest.java @@ -0,0 +1,58 @@ +package test.com.jd.blockchain.crypto.utils.classic; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder; + + +import java.io.IOException; +import java.security.*; + +/** + * @author zhanglin33 + * @title: CSRTest + * @description: TODO + * @date 2019-05-10, 12:55 + */ +public class CSRTest { + 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; + } +} diff --git a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/CertTest.java b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/CertTest.java new file mode 100644 index 00000000..94e5ad24 --- /dev/null +++ b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/CertTest.java @@ -0,0 +1,81 @@ +package test.com.jd.blockchain.crypto.utils.classic; + +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; +import org.junit.Test; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.NoSuchProviderException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +/** + * @author zhanglin33 + * @title: CertTest + * @description: TODO + * @date 2019-05-09, 11:34 + */ +public class CertTest { + + private byte[] certBytes = Base64.decode("MIIEQDCCAyigAwIBAgIFICdVYzEwDQYJKoZIhvcNAQEFBQAwWTELMAkGA1UEBhMCQ04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEYMBYGA1UEAxMPQ0ZDQSBURVNUIE9DQTExMB4XDTE5MDUxMDExMjAyNFoXDTIxMDUxMDExMjAyNFowcjELMAkGA1UEBhMCQ04xGDAWBgNVBAoTD0NGQ0EgVEVTVCBPQ0ExMTERMA8GA1UECxMITG9jYWwgUkExFTATBgNVBAsTDEluZGl2aWR1YWwtMTEfMB0GA1UEAxQWMDUxQGFhYWFhQFpIMDkzNTgwMjhAMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJx3F2WD1dJPzK/nRHO7d1TJ1hTjzGTmv0PQ7ECsJAh3U3BtnGTpCB+b4+JMI4LO8nHkKIBQ3P9XnF+Bf1iXdWNAQ4aWCxa2nV7lCp4w0GliPu/EMgIfmsSDUtgqbM3cr8sR8r9m1xG3gt2TIQJ+jT7sAiguU/kyNzpjaccOUIgUFa8IDFq9UeB76MXtCuhlERRZQCl47e+9w7ZoxmE7e6IZORxPp7rQWVBHlR9ntWjJfNDTm3gMP5ehP+yIZnKx1LudxkBLQxpMmspzOyH1zqx5nkKe49AfWWpDxxRvYkriyYC3aE81qLsU/bhLwNEKOju7BGDF/mhJLZUedojM0gMCAwEAAaOB9TCB8jAfBgNVHSMEGDAWgBT8C7xEmg4xoYOpgYcnHgVCxr9W+DBIBgNVHSAEQTA/MD0GCGCBHIbvKgECMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMvdXMtMTUuaHRtMDoGA1UdHwQzMDEwL6AtoCuGKWh0dHA6Ly8yMTAuNzQuNDIuMy9PQ0ExMS9SU0EvY3JsMjU2OTMuY3JsMAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQU5oKGaQs7Jt5Gfbt1XhFTWAySEKswHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEBBQUAA4IBAQAlmPRaImZV51iKjtpMKuyLMw7dX8L0lY3tl+pVZZSxHuwsN4GCCtV0Ej50up+/6EbfL4NUTiuHVAjCroKKvb+94CrdEwdnQGM5IbGSjT78nQpeASXbIWuUwA+ImjvZOzvq/0b56AzonNzBxOMGko/bj5smM6X8jrgJ0NQppo2KNSVNC4JbuoNWI4FM94SE4DUi9H7EYl4JdOtDaDtCsq49o/A1CZyYrmoOPCgxpQQXmuB3lGq/jyoOlW2aW8uee/hYG1JJcSHLBjF0WBwdxssgbBotA5f1PebiIMSbFgjk57bd4M80hhU/rI4Hkn9pcp5R7NsX95TtyDIg90LboBnW"); + public static String getSubjectDN(byte[] der) { + String dn = ""; + try { + ByteArrayInputStream bIn = new ByteArrayInputStream(der); + //BouncyCastleProvider provider = new BouncyCastleProvider(); + //CertificateFactory cf = CertificateFactory.getInstance("X509", + //provider); + //CertificateFactory cf = CertificateFactory.getInstance("X.509", + // "SUN"); + //android 需采用bcprov + CertificateFactory cf = CertificateFactory.getInstance("X.509"); +// System.out.println(cf.getProvider().getName()); + X509Certificate cert = (X509Certificate) cf + .generateCertificate(bIn); + dn = cert.getSubjectDN().getName(); + + System.out.println(Hex.toHexString(cert.getEncoded())); + byte[] pubKeyBytes = cert.getPublicKey().getEncoded(); + System.out.println(Hex.toHexString(pubKeyBytes)); + System.out.println(cert.getSigAlgName()); + String issuerName = cert.getIssuerDN().getName(); + System.out.println(issuerName); + String oid = cert.getSigAlgOID(); + System.out.println(oid); + System.out.println(); + String name = cert.getIssuerX500Principal().getName(); + System.out.println(name); + bIn.close(); + } catch (CertificateException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return dn; + } + + +// public static String parseCertDN(String dn, String type) { +// type = type + "="; +// String[] split = dn.split(","); +// for (String x : split) { +// if (x.contains(type)) { +// x = x.trim(); +// return x.substring(type.length()); +// } +// } +// return null; +// } + + + @Test + public void cert1Test() { + String string = getSubjectDN(certBytes); + System.out.println(Hex.toHexString(certBytes)); + System.out.println(string); + } +} diff --git a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/RSAUtilsTest.java b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/RSAUtilsTest.java index 3e68c8c6..982cd35e 100644 --- a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/RSAUtilsTest.java +++ b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/RSAUtilsTest.java @@ -1,16 +1,22 @@ package test.com.jd.blockchain.crypto.utils.classic; import com.jd.blockchain.crypto.utils.classic.RSAUtils; +import org.bouncycastle.asn1.DERNull; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.params.AsymmetricKeyParameter; import org.bouncycastle.crypto.params.RSAKeyParameters; import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; +import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; +import org.bouncycastle.util.encoders.Hex; import org.junit.Test; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; +import java.io.IOException; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; @@ -27,7 +33,7 @@ import static org.junit.Assert.*; public class RSAUtilsTest { @Test - public void generateKeyPairTest(){ + public void generateKeyPairTest() throws IOException { AsymmetricCipherKeyPair kp = RSAUtils.generateKeyPair(); RSAKeyParameters pubKey = (RSAKeyParameters) kp.getPublic(); RSAPrivateCrtKeyParameters privKey = (RSAPrivateCrtKeyParameters) kp.getPrivate(); @@ -59,6 +65,17 @@ public class RSAUtilsTest { byte[] pubKeyBytesConverted_PKCS8 = RSAUtils.pubKey2Bytes_PKCS8(RSAUtils.bytes2PubKey_PKCS8(pubKeyBytes_PKCS8)); assertArrayEquals(pubKeyBytes_PKCS8,pubKeyBytesConverted_PKCS8); +// +//// String str = "1.2.840.113549.1.1"; +//// System.out.println(Hex.toHexString(str.getBytes())); +// byte[] bytes = null; +// AlgorithmIdentifier RSA_ALGORITHM_IDENTIFIER = +// new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, DERNull.INSTANCE); +//// byte[] result = KeyUtil.getEncodedSubjectPublicKeyInfo(RSA_ALGORITHM_IDENTIFIER, bytes); +// byte[] algo = RSA_ALGORITHM_IDENTIFIER.getEncoded(); +// System.out.println(Hex.toHexString(algo)); +//// System.out.println(Hex.toHexString(result)); +// System.out.println(Hex.toHexString(pubKeyBytes_PKCS8)); byte[] privKeyBytes_PKCS8 = RSAUtils.privKey2Bytes_PKCS8(privKey); byte[] privKeyBytesConverted_PKCS8 = diff --git a/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/SSHKeyUtilsTest.java b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/SSHKeyUtilsTest.java new file mode 100644 index 00000000..1c2d7731 --- /dev/null +++ b/source/crypto/crypto-classic/src/test/java/test/com/jd/blockchain/crypto/utils/classic/SSHKeyUtilsTest.java @@ -0,0 +1,212 @@ +package test.com.jd.blockchain.crypto.utils.classic; + +import org.bouncycastle.asn1.ASN1Sequence; +import org.bouncycastle.crypto.params.RSAKeyParameters; +import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters; +import org.bouncycastle.crypto.util.OpenSSHPrivateKeyUtil; +import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil; +import org.bouncycastle.jce.spec.OpenSSHPrivateKeySpec; +import org.bouncycastle.jce.spec.OpenSSHPublicKeySpec; +import org.bouncycastle.util.Strings; +import org.bouncycastle.util.encoders.Base64; +import org.bouncycastle.util.encoders.Hex; +import org.bouncycastle.util.io.pem.PemReader; +import org.junit.Test; + +import java.io.IOException; +import java.io.StringReader; +import java.math.BigInteger; + +/** + * @author zhanglin33 + * @title: SSHKeyUtilsTest + * @description: Tests for methods in SSHKeyUtils + * @date 2019-05-07, 15:14 + */ +public class SSHKeyUtilsTest { + + @Test + public void parseRSAPublicKeyTest() { + + String pubKeyStr = "AAAAB3NzaC1yc2EAAAADAQABAAABAQCYwLN4EXy7g0Xugv4lQfoujbARi48gPSxVupt" + + "GsSoGqsS00e9rA7v0qzFKa9Zhnw1WkjCnEXRYAMiCAJYkM/mGI8mb3qkcdNhGWZmPnopV+D46CTFB1" + + "4yeR9mjoOPXs4pjX3zGveKx5Nx8jvdoFewbTCtdN0x1XWTjNT5bXqP/4gXkLENEU5tLsWVAOu0ME/N" + + "e/9gMujAtDoolJ181a9P06bvEpIw5cLtUnsm5CtvBuiL7WBXxDJ/IASJrKNGBdK8xib1+Kb8tNLAT6" + + "Dj25BwylqiRNhb5l1Ni4aKrE2FqSEc5Nx5+csQMEl9MBJ3pEsLHBNbohDL+jbwLguRVD6CJ"; + + byte[] pubKeyBytes = Base64.decode(pubKeyStr); + System.out.println(Hex.toHexString(pubKeyBytes)); + OpenSSHPublicKeySpec pubKeySpec = new OpenSSHPublicKeySpec(pubKeyBytes); + + String pubKeyFormat = pubKeySpec.getFormat(); + String pubKeyType = pubKeySpec.getType(); + System.out.println(pubKeyFormat); + System.out.println(pubKeyType); + + RSAKeyParameters pubKey = (RSAKeyParameters) OpenSSHPublicKeyUtil.parsePublicKey(pubKeyBytes); + BigInteger e = pubKey.getExponent(); + BigInteger n = pubKey.getModulus(); + System.out.println(Hex.toHexString(e.toByteArray())); + System.out.println(Hex.toHexString(n.toByteArray())); + + System.out.println(); + System.out.println("-------------------------------------------------------"); + System.out.println(); + + + } + + @Test + public void parseRSAPrivateKeyTest() { + + String str2 = "-----BEGIN OPENSSH PRIVATE KEY-----\n" + + "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n" + + "NhAAAAAwEAAQAAAQEAwFyeWgHFu/ZMvqWa28QUGlKMDV7vpbzT7kyA/4yuotfprZKHNeEy\n" + + "GugleJ/Kv5kqHh8Km4IZcfNcerTYds+U5m/uX4bSYpEbXco3DQ2lYQbYo7PBWwPMq2aIdd\n" + + "i7WxUAlt0z1ugLNimskPzJ7DNra+ax0Wh9RnMsjZkfuBZiKq7wbBm7NyJmpg2B7xo5cz+G\n" + + "Lw9e0tDlvgeLe+n68WvYWWFP59mfP6Qoy+NwjQnnwrhJi2j4dEexO97KmgnJhL07lu4eCQ\n" + + "fdv68Tai9+aeDNawe7nmFYf2eNjah2jW/DwOwA/ErXnvgjLSMsgc6WGKfokhytAOFDGgvH\n" + + "KKNd6BMYZwAAA9A7JircOyYq3AAAAAdzc2gtcnNhAAABAQDAXJ5aAcW79ky+pZrbxBQaUo\n" + + "wNXu+lvNPuTID/jK6i1+mtkoc14TIa6CV4n8q/mSoeHwqbghlx81x6tNh2z5Tmb+5fhtJi\n" + + "kRtdyjcNDaVhBtijs8FbA8yrZoh12LtbFQCW3TPW6As2KayQ/MnsM2tr5rHRaH1GcyyNmR\n" + + "+4FmIqrvBsGbs3ImamDYHvGjlzP4YvD17S0OW+B4t76frxa9hZYU/n2Z8/pCjL43CNCefC\n" + + "uEmLaPh0R7E73sqaCcmEvTuW7h4JB92/rxNqL35p4M1rB7ueYVh/Z42NqHaNb8PA7AD8St\n" + + "ee+CMtIyyBzpYYp+iSHK0A4UMaC8coo13oExhnAAAAAwEAAQAAAQAEEvIXnen+LR06/G7n\n" + + "MKPsWss0jUouDG3AokYpI2WfdUsxreTHM1nIUBpbD6dPn4LQ2H91A7BeRXUz9BiRi5vvtX\n" + + "cq9sQF6mTV+65mzF8wSuDTtr7lmpL/HlDNjiWJrEwy5cRvTMLQBtnsyC3OntgrlNs3QCtH\n" + + "DrFm3lNZpr+1f62Vu43dbcTPvLwcc335cJ73BU5WsMGaouCAqVXsVsgfkA66u6+gQs8O3F\n" + + "IQntdzS8vYpkzH8N9qqNZit7kbFCRUTI7CDLHquJmclzB8uVwO0pR5+Aross+YL3QxPZoJ\n" + + "+LXLlCi27oSmYk3fx3uh0XwwO3JFDQpeCxOuEsZbOy8BAAAAgCsktFksS0BViRuLyzC2H7\n" + + "X7Uonf+dr8e4Yn+RgR329KFh/ok28/KZndZHsUnhdmiIjPr+SplFZZMrV/uJDkGezUNWGf\n" + + "8qn+eEglm7nYfVf2EXTVNhpg8yfPChx90ybc8GYlqpEqf7LiCuEBCPqPJgq6K7i6UKbwn2\n" + + "SfqUOBcz5BAAAAgQDqszdiNv0cTvZ/Xg3qJPsHXqQuLBYoe2vhU+Pipt9HviruUD1y3Mso\n" + + "rOL9QBwjE7szGnwVE00J0mLp+s309+kftADLXqMyqFYiy7S8GIWQw0YNB2m8yjq+phHbBm\n" + + "/Gs2P4+s8yKTcVJvMTyWr02rpCHiLTKDHoXPJcJ8yVMTHFRwAAAIEA0dHB9fXiesEKfwcp\n" + + "X11IHAV8pTd+7VN81oGwxtRg88U7H2rmQFCxSZah2O/OCCmYLH3PHT95qnMHHqzcsVvoIy\n" + + "7AfnMpp4KYU0Ic3aFuRjZk2sDsYUniPcCpuCvs8Jb75sDwKDW2EM8MowiNylDnYMmfYj0l\n" + + "gIhz1/p79hXEI+EAAAAbemhhbmdsaW4zM0B6aGFuZ2xpbjMzLmxvY2Fs\n" + + "-----END OPENSSH PRIVATE KEY-----"; + + byte[] Bytes2 = null; + try { + Bytes2 = new PemReader(new StringReader(str2)).readPemObject().getContent(); + } catch (IOException e1) { + e1.printStackTrace(); + } + System.out.println(Hex.toHexString(Bytes2)); + + String str3 = "-----BEGIN OPENSSH PRIVATE KEY-----\n" + + "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n" + + "NhAAAAAwEAAQAAAQEAvummQZm1FUFc/cV5nQBeowhjX4vIU4kBmyPmXHMViX4ORvWvD1yi\n" + + "oxcaawPpP9QconpzjdCrNbmw0oZNt9UKlmrOU34YTRD5LFlEVOYjr/21/SO5yDGog8xJBU\n" + + "HQYnXY5L2q9EXKOF45e5P6gSGUovrhePEsaniuQN48GIObPCOFkEN0ZV2DqRsn3It1vY+D\n" + + "GiSb5EaZ2sNkudyzYfgFxcCbqBXmDa1WeyX5xYh8wldBJLUH+pO4gPoTXXX4UI4yNdDmPD\n" + + "BWFvPVIOdpfdBnDbEp1AoE5Jx/+tbwFBIEvTPOECtOUKDGIlXXIH0I4waHbwf6EnHD5+BR\n" + + "N0XwrzSkuwAAA9DYV/7H2Ff+xwAAAAdzc2gtcnNhAAABAQC+6aZBmbUVQVz9xXmdAF6jCG\n" + + "Nfi8hTiQGbI+ZccxWJfg5G9a8PXKKjFxprA+k/1ByienON0Ks1ubDShk231QqWas5TfhhN\n" + + "EPksWURU5iOv/bX9I7nIMaiDzEkFQdBiddjkvar0Rco4Xjl7k/qBIZSi+uF48SxqeK5A3j\n" + + "wYg5s8I4WQQ3RlXYOpGyfci3W9j4MaJJvkRpnaw2S53LNh+AXFwJuoFeYNrVZ7JfnFiHzC\n" + + "V0EktQf6k7iA+hNddfhQjjI10OY8MFYW89Ug52l90GcNsSnUCgTknH/61vAUEgS9M84QK0\n" + + "5QoMYiVdcgfQjjBodvB/oSccPn4FE3RfCvNKS7AAAAAwEAAQAAAQArRruxUy6BSvfRbtpK\n" + + "hLLvMg+UsRMQHJaInHKzskLHkBOcckTkrpMPdUU/zPsqxOJY0nkvRIYK/7TdhCRJ77ker8\n" + + "dllcfccGSLcRDUTfb5BgIjB94tS1Rvy/chgfHC4APyliwSg197t6BAKyM18m7HIyfJSqJO\n" + + "4FxfyADHbc3aq654tu+eaUtD7TEN1bH6PKMDvwSioMLgKU43GQeDJZbqamBE9y+KVhVx9y\n" + + "3DEHrOPkRkZIG33y9j7B/i0vl+WnwUTzmLGRR0U6J9wrzyANL8ODYaAvk4FvUED8hQ72jh\n" + + "NpAXsSgf6COUE1sUnO5DOwN1zHBNHaSo73Qu7aKZtL4BAAAAgDBW3ItiqU9Ip34KtLaayK\n" + + "/BkRDDwFNvAxpOw9alpfbLGF5xbVjRN4wy7HJ4eA+7JJnx6A6xYrzykbPP+dnUnfzYuxH8\n" + + "MrihOkYipw1VaR6/0XH+apmE1SmotuYbl+bpl9dlZYUI0pJ8wldqoDCNlSOcLy77HnKwu9\n" + + "GpJx9KmW9WAAAAgQDdnrwfVv5trAuZZIcw2vLRWhoDT196k/Ty1GP4zFpDttb8OyZ8Ygpx\n" + + "oA5PhYyl5M1g/2oR/Rpp3vfKDVThfn/bCnMtAbUHMfvYK3Oufvq5JmzT1rgGr3MEek+JBR\n" + + "O17I87m4GE7iM1LzCUs2G/fKt2uoVXdniv0Vn0iCiZZc7JmwAAAIEA3IdsccarkUfFcQ2c\n" + + "4TdHrx/RGmoTAO6k1xOHXZjWPmerinuOspIJL/ymWfqIxABCjub3UHyP7ap+1+AAnk+TMU\n" + + "eR3tLEp9tRM6n0Td56DnQ9Q+RZhPqR486/teZ33cMBMHg52aIs/3AzMpK9xTFCRgqsKa6e\n" + + "ednMB4Q1txvHU2EAAAAbemhhbmdsaW4zM0B6aGFuZ2xpbjMzLmxvY2Fs\n" + + "-----END OPENSSH PRIVATE KEY-----"; + + byte[] Bytes3 = null; + try { + Bytes3 = new PemReader(new StringReader(str3)).readPemObject().getContent(); + } catch (IOException e1) { + e1.printStackTrace(); + } + System.out.println(Hex.toHexString(Bytes3)); +// System.out.println(Hex.toHexString(Base64.decode("oNE9iA4ZyuZLbpEL7B29NaxGi4puT2Y5RDaMoEkoAKI"))); +// String test = "1ac477fa"; +// byte[] testBytes = Hex.decode(test); +// +// System.out.println(Base64.toBase64String(testBytes)); + + byte[] AUTH_MAGIC = Strings.toByteArray("openssh-key-v1\0"); + System.out.println(Hex.toHexString(AUTH_MAGIC)); + System.out.println(Base64.toBase64String(AUTH_MAGIC)); + String privKeyStr = "-----BEGIN OPENSSH PRIVATE KEY-----\n" + + "b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn\n" + + "NhAAAAAwEAAQAAAQEAmMCzeBF8u4NF7oL+JUH6Lo2wEYuPID0sVbqbRrEqBqrEtNHvawO7\n" + + "9KsxSmvWYZ8NVpIwpxF0WADIggCWJDP5hiPJm96pHHTYRlmZj56KVfg+OgkxQdeMnkfZo6\n" + + "Dj17OKY198xr3iseTcfI73aBXsG0wrXTdMdV1k4zU+W16j/+IF5CxDRFObS7FlQDrtDBPz\n" + + "Xv/YDLowLQ6KJSdfNWvT9Om7xKSMOXC7VJ7JuQrbwboi+1gV8QyfyAEiayjRgXSvMYm9fi\n" + + "m/LTSwE+g49uQcMpaokTYW+ZdTYuGiqxNhakhHOTcefnLEDBJfTASd6RLCxwTW6IQy/o28\n" + + "C4LkVQ+giQAAA9AaxHf6GsR3+gAAAAdzc2gtcnNhAAABAQCYwLN4EXy7g0Xugv4lQfoujb\n" + + "ARi48gPSxVuptGsSoGqsS00e9rA7v0qzFKa9Zhnw1WkjCnEXRYAMiCAJYkM/mGI8mb3qkc\n" + + "dNhGWZmPnopV+D46CTFB14yeR9mjoOPXs4pjX3zGveKx5Nx8jvdoFewbTCtdN0x1XWTjNT\n" + + "5bXqP/4gXkLENEU5tLsWVAOu0ME/Ne/9gMujAtDoolJ181a9P06bvEpIw5cLtUnsm5CtvB\n" + + "uiL7WBXxDJ/IASJrKNGBdK8xib1+Kb8tNLAT6Dj25BwylqiRNhb5l1Ni4aKrE2FqSEc5Nx\n" + + "5+csQMEl9MBJ3pEsLHBNbohDL+jbwLguRVD6CJAAAAAwEAAQAAAQARfhfPSylei9TpUGTs\n" + + "PVb6F82u5K16QqceFiWL/ePTKaEnF9d0CNRwW15kqF6/hShQ3qLlrvEE1uofQRPwh2cuvl\n" + + "BrIh95m8PcoowcT0qGN8xgdwcGBDodMhsxSs5suCnD4X53f+1C8/Nv7CtW5xPHuHxKy3dd\n" + + "BVn1TvaaHgdn2PwJVKtZp+WVG3/UHr25nFHd8mYgpeHZqK9AW16N0UEMXMM1u8ZCubVOoS\n" + + "IGuMAXpTug0xA+BXHo17FcDGKSzcXFzh+urIz5glRp5zFioHBqxNmkKfQkG6C7UxnPGyS/\n" + + "/J+3lL2lvl0G8kO/5EDFMBhTMEy1NeR2b629S4G1qUxVAAAAgHDwE9kPiVETcxSzI4wotT\n" + + "1Ee9nKVVD3oGdRqefvX7EUR8bvdv4nCqHPNBx8C6l8zo7fsQD81YL85F4eWbtrdxEijRHX\n" + + "5m7J/muh/laY1Hq43WCkZGboO4fZ2HHi7oN096FqrKRpvbQGQi1FLbcISUdsitwrs6ywn3\n" + + "fNx3q+X3V6AAAAgQDJRo9v+0QvldI33cpJKPKiaop5QvfIDzMatD3vLA1qqycgIi4KOtb5\n" + + "+LP/jgIpCYah/sk+JpKNz/vsZmZmrfaVu9D3Le2LLBgMpEoSO8jOe9WGI4Ew75C7w7AZCa\n" + + "SyUnHIVX/9D8Y5tx4cKx6Im9AGbNF35XZoKO4KCk5VMTXhnwAAAIEAwkjKIpTYdeAQVTRf\n" + + "C13kg84Bu5n4WkiLnp1WOCg2GN5RekqprINtpjIMZoB9Fv292Np99La8yvmRoy5qzNHGdm\n" + + "Q6AMku8jP123jF2J+wDvF714VtZHNvdCYBGJS+rZ81xtJfHhKtZqRAVtbPertOWZeuRm9V\n" + + "o+/rEuEzgGYGXNcAAAAbemhhbmdsaW4zM0B6aGFuZ2xpbjMzLmxvY2Fs\n" + + "-----END OPENSSH PRIVATE KEY-----"; + + byte[] privKeyBytes = null; + try { + privKeyBytes = new PemReader(new StringReader(privKeyStr)).readPemObject().getContent(); + } catch (IOException e1) { + e1.printStackTrace(); + } + + assert privKeyBytes != null; + System.out.println(Hex.toHexString(privKeyBytes)); + + + OpenSSHPrivateKeySpec privKeySpec = new OpenSSHPrivateKeySpec(privKeyBytes); + + String privKeyFormat = privKeySpec.getFormat(); + System.out.println(privKeyFormat); + + RSAKeyParameters privKey = (RSAKeyParameters) OpenSSHPrivateKeyUtil.parsePrivateKeyBlob(privKeyBytes); + +// BigInteger e = privKey.getPublicExponent(); +// BigInteger n = privKey.getModulus(); +// +// BigInteger d = privKey.getExponent(); +// BigInteger p = privKey.getP(); +// BigInteger q = privKey.getQ(); +// BigInteger dP = privKey.getDP(); +// BigInteger dQ = privKey.getDQ(); +// BigInteger qInv = privKey.getQInv(); + +// System.out.println(Hex.toHexString(e.toByteArray())); +// System.out.println(Hex.toHexString(n.toByteArray())); +// +// System.out.println(Hex.toHexString(d.toByteArray())); +// System.out.println(Hex.toHexString(p.toByteArray())); +// System.out.println(Hex.toHexString(q.toByteArray())); +// System.out.println(Hex.toHexString(dP.toByteArray())); +// System.out.println(Hex.toHexString(dQ.toByteArray())); +// System.out.println(Hex.toHexString(qInv.toByteArray())); + + + + } + +} diff --git a/source/crypto/crypto-pki/pom.xml b/source/crypto/crypto-pki/pom.xml new file mode 100644 index 00000000..5256127d --- /dev/null +++ b/source/crypto/crypto-pki/pom.xml @@ -0,0 +1,34 @@ + + + + crypto + com.jd.blockchain + 0.9.0-SNAPSHOT + + 4.0.0 + + crypto-pki + + + + com.jd.blockchain + crypto-classic + ${project.version} + + + org.bouncycastle + bcprov-jdk15on + 1.61 + + + + org.bouncycastle + bcpkix-jdk15on + 1.61 + + + + + \ No newline at end of file diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CSRBuilder.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CSRBuilder.java new file mode 100644 index 00000000..76f16247 --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CSRBuilder.java @@ -0,0 +1,10 @@ +package com.jd.blockchain.crypto; + +/** + * @author zhanglin33 + * @title: CSRBuilder + * @description: A builder for certificate signing request, supporting rsa and sm2 + * @date 2019-05-10, 15:10 + */ +public class CSRBuilder { +} diff --git a/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CertParser.java b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CertParser.java new file mode 100644 index 00000000..480b833c --- /dev/null +++ b/source/crypto/crypto-pki/src/main/java/com/jd/blockchain/crypto/CertParser.java @@ -0,0 +1,10 @@ +package com.jd.blockchain.crypto; + +/** + * @author zhanglin33 + * @title: CertParser + * @description: TODO + * @date 2019-05-10, 15:17 + */ +public class CertParser { +} diff --git a/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CSRBuilderTest.java b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CSRBuilderTest.java new file mode 100644 index 00000000..42ecff9e --- /dev/null +++ b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CSRBuilderTest.java @@ -0,0 +1,161 @@ +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.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.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.junit.Test; +import sun.security.rsa.RSAPublicKeyImpl; + +import java.io.IOException; +import java.security.*; + +import static org.junit.Assert.fail; + +/** + * @author zhanglin33 + * @title: CSRBuilderTest + * @description: TODO + * @date 2019-05-10, 17:22 + */ +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 + 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(); + + + X500NameBuilder x500NameBld = new X500NameBuilder(BCStyle.INSTANCE); + + 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"); + + x500NameBld.addRDN(BCStyle.EmailAddress, "feedback-crypto@bouncycastle.org"); + + 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); + + if (!req2.isSignatureValid(new JcaContentVerifierProviderBuilder().setProvider(provider).build(kp.getPublic()))) { + fail(sigName + ": Failed verify check."); + } + + if (!Arrays.areEqual(req2.getPublicKey().getEncoded(), req1.getSubjectPublicKeyInfo().getEncoded())) { + fail(keyName + ": Failed public key check."); + } + } + +} diff --git a/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CertParserTest.java b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CertParserTest.java new file mode 100644 index 00000000..3a8ecc7a --- /dev/null +++ b/source/crypto/crypto-pki/src/test/java/com/jd/blockchain/crypto/CertParserTest.java @@ -0,0 +1,10 @@ +package com.jd.blockchain.crypto; + +/** + * @author zhanglin33 + * @title: CertParserTest + * @description: TODO + * @date 2019-05-13, 10:05 + */ +public class CertParserTest { +} diff --git a/source/crypto/pom.xml b/source/crypto/pom.xml index fb6e71ba..f8b66416 100644 --- a/source/crypto/pom.xml +++ b/source/crypto/pom.xml @@ -16,6 +16,7 @@ crypto-sm crypto-adv + crypto-pki \ No newline at end of file diff --git a/source/pom.xml b/source/pom.xml index 6b1da241..35de30f4 100644 --- a/source/pom.xml +++ b/source/pom.xml @@ -281,6 +281,12 @@ bcprov-jdk15on 1.61 + + + org.bouncycastle + bcpkix-jdk15on + 1.61 + io.nats