diff --git a/src/main/java/com/sunyard/util/CertUtil.java b/src/main/java/com/sunyard/util/CertUtil.java index a7e46a8..2a40df6 100644 --- a/src/main/java/com/sunyard/util/CertUtil.java +++ b/src/main/java/com/sunyard/util/CertUtil.java @@ -1,19 +1,82 @@ package com.sunyard.util; +import cn.hutool.core.codec.Base64; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import sun.misc.BASE64Encoder; +import java.io.ByteArrayInputStream; +import java.security.NoSuchProviderException; +import java.security.Security; +import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Map; + public class CertUtil { public static String encodeBase64(byte[] data){ return new BASE64Encoder().encode( data ); } + static { + Security.addProvider(new BouncyCastleProvider()); + } + + public static X509Certificate convertToX509Cert(String certificateString) throws CertificateException, NoSuchProviderException { +// X509Certificate certificate = null; +// CertificateFactory cf = null; +// try { +// if (certificateString != null && !certificateString.trim().isEmpty()) { +// certificateString = certificateString.replace("-----BEGIN CERTIFICATE-----\n", "") +// .replace("-----END CERTIFICATE-----", ""); // NEED FOR PEM FORMAT CERT STRING +// byte[] certificateData = Base64.decode(certificateString); +// cf = CertificateFactory.getInstance("X509"); +// certificate = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(certificateData)); +// } +// } catch (CertificateException e) { +// throw new CertificateException(e); +// } +// return certificate; + CertificateFactory CF = CertificateFactory.getInstance("X.509", "BC"); // 从证书工厂中获取X.509的单例类 + return (X509Certificate) CF.generateCertificate(new ByteArrayInputStream(certificateString.getBytes())); // 将文件流的证书转化为证书类 + } + + public static String convertToPem(X509Certificate cert) throws CertificateEncodingException { + + String cert_begin = "-----BEGIN CERTIFICATE-----\n"; + String end_cert = "\n-----END CERTIFICATE-----"; + + byte[] derCert = cert.getEncoded(); + String pemCertPre = new String(Base64.encode(derCert, true)); + String pemCert = cert_begin + pemCertPre + end_cert; + return pemCert; +// StringWriter sw = new StringWriter(); +// PemWriter pw = new PemWriter(sw); +// try { +// pw.writeObject(new JcaMiscPEMGenerator(cert)); +// }catch ( Exception e ) { +// e.printStackTrace(); +// }finally { +// if (null == pw) { +// try { +// pw.close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// } +// return sw.toString(); + } + /** * 判断正式是否是国密证书 * @param cert 证书 base64 字符 * @return true 国密, false 非国密 */ - public static boolean isSM2Cert(String cert){ - + public static boolean isSM2Cert(String cert) throws CertificateException, NoSuchProviderException { + X509Certificate certificate = convertToX509Cert(cert); + String signAlg = certificate.getSigAlgName(); + return signAlg.toUpperCase().indexOf("SM2") >= 0; } /** @@ -22,7 +85,7 @@ public class CertUtil { * @return true 国密, false 非国密 */ public static boolean isSignedBySM2Cert( String pkcs7 ){ - + return false; } diff --git a/src/test/java/com/sunyard/sydapi/test/TestCertUtil.java b/src/test/java/com/sunyard/sydapi/test/TestCertUtil.java new file mode 100644 index 0000000..ce3bcef --- /dev/null +++ b/src/test/java/com/sunyard/sydapi/test/TestCertUtil.java @@ -0,0 +1,73 @@ +package com.sunyard.sydapi.test; + +import com.sunyard.util.CertUtil; +import org.junit.Assert; +import org.junit.Test; + +import java.io.IOException; +import java.io.InputStream; +import java.security.NoSuchProviderException; +import java.security.cert.CertificateException; + +public class TestCertUtil { + + + private static String readCert(String cert){ + InputStream is = TestCertUtil.class.getResourceAsStream(cert); + byte[] data = new byte[0]; + try { + data = new byte[is.available()]; + is.read( data ); + } catch (IOException e) { + e.printStackTrace(); + } + return new String( data ); + } + + @Test + public void case1() throws CertificateException, NoSuchProviderException { + Assert.assertTrue( + CertUtil.isSM2Cert(readCert("/x509/c1.crt")) + ); + } + + @Test + public void case2() throws CertificateException, NoSuchProviderException { + Assert.assertTrue( + CertUtil.isSM2Cert(readCert("/x509/c2.crt")) + ); + } + + @Test + public void case3() throws CertificateException, NoSuchProviderException { + + // 此证书是错误的 + try { + CertUtil.isSM2Cert(readCert("/x509/c3.crt")); + } catch ( CertificateException e ) { + e.printStackTrace(); + } + } + + @Test + public void case4() throws CertificateException, NoSuchProviderException { + Assert.assertTrue( + CertUtil.isSM2Cert(readCert("/x509/c4.crt")) + ); + } + + @Test + public void case5() throws CertificateException, NoSuchProviderException { + Assert.assertFalse( + CertUtil.isSM2Cert(readCert("/x509/c5.crt")) + ); + } + + @Test + public void case6() throws CertificateException, NoSuchProviderException { + Assert.assertTrue( + CertUtil.isSM2Cert(readCert("/x509/c6.crt")) + ); + } + +} diff --git a/src/test/resources/x509/c1.crt b/src/test/resources/x509/c1.crt new file mode 100644 index 0000000..30e9323 --- /dev/null +++ b/src/test/resources/x509/c1.crt @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAoqgAwIBAgIUdopSvvFbnQ5eYTXDbVHVxbzNIr0wDAYIKoEcz1UBg3UFADCBjTFHMEUGA1UEAww+U2hlbiBaaGVuIGlUcnVzQ2hpbmEgQ2xhc3MgRW50ZXJwcmlzZSBTdWJzY3JpYmVyIENBIFNNMiAtIFRlc3QxGDAWBgNVBAsMD+a1i+ivlemDqOivleeUqDEbMBkGA1UECgwS5aSp6K+a5a6J5L+h6K+V55SoMQswCQYDVQQGEwJDTjAeFw0yMTA5MjQwOTAxNDlaFw0yMTEwMzAwOTAxNDlaMIGJMTAwLgYDVQQGDCfkv6Hpm4Xovr7ns7vnu5/lt6XnqIvogqHku73mnInpmZDlhazlj7gxMDAuBgNVBAoMJ+S/oembhei+vuezu+e7n+W3peeoi+iCoeS7veaciemZkOWFrOWPuDEVMBMGA1UECwwM5rWL6K+V6YOo6ZeoMQwwCgYDVQQDDAN0c3owWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAQrGLBAbah3raYHtPPz1M2Uo0S8/I5FaXUfiFlIsRG83kptcNkhqs3nExpDONr/MEwA5RPy1NykY4NTExFxRL1Zo4HHMIHEMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgbAMGoGA1UdHwRjMGEwX6BdoFuGWWh0dHA6Ly9zenRvcGNhLnN6aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT03MzM1QTFBRjM3NEExRThCNDAzQUIxQUMyRDA2NUNBRTc1Q0FCMjM2MB8GA1UdIwQYMBaAFCtGOk/RnizO1B+GwtY9mr8nKGT3MB0GA1UdDgQWBBQXy1yrr19MSEI6oNqflnpRANrYsjAMBggqgRzPVQGDdQUAA0gAMEUCIQCXL/2421/WNysyRJywGnvqb7//kQHesxJOYR/Wx+Cy0wIgFMg6d1EnbtG7P7CBb1cpE28wL3CJ0MhLsj1kWJ83urc= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/src/test/resources/x509/c2.crt b/src/test/resources/x509/c2.crt new file mode 100644 index 0000000..bf06c4a --- /dev/null +++ b/src/test/resources/x509/c2.crt @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +MIIC/jCCAqGgAwIBAgIUNsxEN14yKYS46MMd49zV1VBX86gwDAYIKoEcz1UBg3UFADCBjTFHMEUGA1UEAww+U2hlbiBaaGVuIGlUcnVzQ2hpbmEgQ2xhc3MgRW50ZXJwcmlzZSBTdWJzY3JpYmVyIENBIFNNMiAtIFRlc3QxGDAWBgNVBAsMD+a1i+ivlemDqOivleeUqDEbMBkGA1UECgwS5aSp6K+a5a6J5L+h6K+V55SoMQswCQYDVQQGEwJDTjAeFw0yMTA5MjQwOTAxNDlaFw0yMTEwMzAwOTAxNDlaMIGJMTAwLgYDVQQGDCfkv6Hpm4Xovr7ns7vnu5/lt6XnqIvogqHku73mnInpmZDlhazlj7gxMDAuBgNVBAoMJ+S/oembhei+vuezu+e7n+W3peeoi+iCoeS7veaciemZkOWFrOWPuDEVMBMGA1UECwwM5rWL6K+V6YOo6ZeoMQwwCgYDVQQDDAN0c3owWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAASvEw1Xvtb7aKgE6B2Kza6qAQ+v46IK+RW+iew1vYIuav1OWnig8HZyPLbS9xbBMEza4rabYYVtJV0gMKpd4q9ao4HeMIHbMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgUgMGoGA1UdHwRjMGEwX6BdoFuGWWh0dHA6Ly9zenRvcGNhLnN6aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT03MzM1QTFBRjM3NEExRThCNDAzQUIxQUMyRDA2NUNBRTc1Q0FCMjM2MB8GA1UdIwQYMBaAFCtGOk/RnizO1B+GwtY9mr8nKGT3MB0GA1UdDgQWBBT8wguWmfR6babqxuMlFuomK34BEzAVBgdggRwBBgoCBAoMCElUUlVTS01DMAwGCCqBHM9VAYN1BQADSQAwRgIhAOQBN76TqGS4tMg4RpZhCA0WrEI/LbR4HBYRi3cENaAsAiEA/MKRt81na+cr4Lqi8ew2OyEoZ56/W3Sbwijd3D1Rrok= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/src/test/resources/x509/c3.crt b/src/test/resources/x509/c3.crt new file mode 100644 index 0000000..f5dd7d3 --- /dev/null +++ b/src/test/resources/x509/c3.crt @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +MIHGAgECBIHA/FjfJkcNPEqGRLtdEV2k2TTszxsBf6KzZM02wxJ+tQJqEHGjxSv61CckxcdSS8J3KnsVmKHmfhlB4qNiB+l2WX9aqN2SYKugBqPm5yujgg+MIjvseK3aHJv1RKzdlY99lk/foF64Xoqev4yrb/1QlULTKTmXxBWvHy8eDqmmrK61WNDNwRpQkblU8+m1jpcYO6pYZ7FhhyIwSFfgton/0YqaEuFko0shZT+N5Uo+8Xj9Si+klf1g0ZkXyLBvu2BK +-----END CERTIFICATE----- \ No newline at end of file diff --git a/src/test/resources/x509/c4.crt b/src/test/resources/x509/c4.crt new file mode 100644 index 0000000..009b817 --- /dev/null +++ b/src/test/resources/x509/c4.crt @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAqSgAwIBAgIUGQmQP1Ihhp+ntGkcW/TEbpg9K4cwDAYIKoEcz1UBg3UFADCBjTFHMEUGA1UEAww+U2hlbiBaaGVuIGlUcnVzQ2hpbmEgQ2xhc3MgRW50ZXJwcmlzZSBTdWJzY3JpYmVyIENBIFNNMiAtIFRlc3QxGDAWBgNVBAsMD+a1i+ivlemDqOivleeUqDEbMBkGA1UECgwS5aSp6K+a5a6J5L+h6K+V55SoMQswCQYDVQQGEwJDTjAeFw0yMjAyMjEwMzE0MzBaFw0yMzAyMjAwMzE0MzBaMIGMMTAwLgYDVQQGDCfkv6Hpm4Xovr7ns7vnu5/lt6XnqIvogqHku73mnInpmZDlhazlj7gxMDAuBgNVBAoMJ+S/oembhei+vuezu+e7n+W3peeoi+iCoeS7veaciemZkOWFrOWPuDEVMBMGA1UECwwM5rWL6K+V6YOo6ZeoMQ8wDQYDVQQDDAYxODAyODAwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAASOXJb83s34i298Xk8WNAkLVdkyMECg3tYbiAKryeeW2IsCbh1fJi/CRi3vo2aWKuegbmJPDZbNWy0D7ZEZ2NaEo4HeMIHbMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgUgMGoGA1UdHwRjMGEwX6BdoFuGWWh0dHA6Ly9zenRvcGNhLnN6aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT03MzM1QTFBRjM3NEExRThCNDAzQUIxQUMyRDA2NUNBRTc1Q0FCMjM2MB8GA1UdIwQYMBaAFCtGOk/RnizO1B+GwtY9mr8nKGT3MB0GA1UdDgQWBBT3OKsoJNvkYyMb9Cn8bEhxQd4NTTAVBgdggRwBBgoCBAoMCElUUlVTS01DMAwGCCqBHM9VAYN1BQADRwAwRAIgbyk9Uxxll87Mqf8RRBhJfXbK5Y5vsfWG4weD5rpGr9oCIDmxuh9ZUXpLCZ0tDuZ9o+0WD+XKe1bMkm3VmJ6vqkRt +-----END CERTIFICATE----- diff --git a/src/test/resources/x509/c5.crt b/src/test/resources/x509/c5.crt new file mode 100644 index 0000000..a57eb5f --- /dev/null +++ b/src/test/resources/x509/c5.crt @@ -0,0 +1,72 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 0 (0x0) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=cn, ST=ca.fullstack.club, L=Hangzhou, O=fullstack.club, OU=ca, CN=ca.fullstack.club/emailAddress=admin@fullstack.club + Validity + Not Before: Nov 8 18:32:07 2017 GMT + Not After : Nov 7 18:32:07 2021 GMT + Subject: C=cn, ST=fullstack.club, L=Hangzhou, O=fullstack.club, OU=all, CN=*.fullstack.club/emailAddress=admin@fullstack.club + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (1024 bit) + Modulus: + 00:ad:fb:a3:5e:b8:93:ff:65:58:82:cd:e5:6d:6d: + 24:e9:b7:7d:9d:b7:ad:04:7e:68:84:ac:fd:76:26: + f8:9c:56:7e:98:b7:eb:69:58:b2:e4:e3:4f:09:0d: + 23:cb:ed:66:80:43:1e:4e:38:4a:7e:d1:09:cf:31: + 76:52:be:d0:23:c8:bf:b3:61:cf:7b:c5:ad:44:0d: + f9:85:7b:4e:7f:68:34:f1:ea:f2:9c:45:7a:41:f7: + 8a:87:b3:e5:60:fa:34:bf:e1:e3:9b:97:db:27:e0: + f7:d3:b7:03:b4:9e:3f:56:51:7d:f9:22:e8:36:dc: + 34:fb:ea:47:f4:60:71:93:8b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + BD:6D:19:B8:70:04:FD:1D:90:0D:D2:ED:6C:0F:58:AE:DC:BE:8F:EF + X509v3 Authority Key Identifier: + keyid:AC:E7:F7:8E:DA:02:06:48:B5:E7:7A:45:38:5C:13:12:99:21:66:EA + + Signature Algorithm: sha256WithRSAEncryption + 3a:32:f5:a8:87:ef:5e:2e:cc:3f:f8:10:4d:8a:a5:dc:be:e0: + 3b:b3:78:43:b5:e5:19:3d:79:ed:82:5d:c4:3d:9c:5a:c3:ff: + 54:c7:3c:a8:ec:b2:a7:7f:78:d4:8e:41:0b:b1:d0:81:06:ed: + 61:b5:15:e2:4c:7c:99:82:f1:93:c1:1a:8f:0d:7a:d4:ae:69: + 2f:4a:60:48:4c:be:3a:e3:40:2e:ed:4d:5c:90:00:1f:51:12: + f6:f9:34:5e:ac:4c:e8:b4:a1:e9:2d:16:af:92:be:00:24:8a: + 00:e2:a3:98:2a:41:cd:2a:5b:21:6d:e5:55:f4:54:df:11:d8: + 9c:1d:e1:9e:82:e7:f5:dd:75:6a:89:13:80:75:36:8d:38:3f: + 3b:96:a2:5e:c2:3f:bf:f0:56:8e:54:93:99:0f:82:90:38:56: + 47:84:9c:f8:0d:5d:45:d3:1f:c6:2b:49:5f:de:2b:b7:62:6e: + 18:47:8e:8d:b4:3d:6e:64:74:86:f3:55:af:13:17:9a:2d:67: + 6a:af:d8:da:68:09:4f:ea:14:69:44:4a:af:34:63:ce:22:9f: + e9:0f:21:14:88:7c:8b:be:e9:fc:b3:ed:19:d4:67:46:87:d7: + 8f:e3:c1:07:d9:f8:e1:f6:5d:a3:2c:e4:3d:61:43:2d:57:2d: + 68:20:12:ad +-----BEGIN CERTIFICATE----- +MIIDtzCCAp+gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBozELMAkGA1UEBhMCY24x +GjAYBgNVBAgMEWNhLmZ1bGxzdGFjay5jbHViMREwDwYDVQQHDAhIYW5nemhvdTEX +MBUGA1UECgwOZnVsbHN0YWNrLmNsdWIxCzAJBgNVBAsMAmNhMRowGAYDVQQDDBFj +YS5mdWxsc3RhY2suY2x1YjEjMCEGCSqGSIb3DQEJARYUYWRtaW5AZnVsbHN0YWNr +LmNsdWIwHhcNMTcxMTA4MTgzMjA3WhcNMjExMTA3MTgzMjA3WjCBoDELMAkGA1UE +BhMCY24xFzAVBgNVBAgMDmZ1bGxzdGFjay5jbHViMREwDwYDVQQHDAhIYW5nemhv +dTEXMBUGA1UECgwOZnVsbHN0YWNrLmNsdWIxDDAKBgNVBAsMA2FsbDEZMBcGA1UE +AwwQKi5mdWxsc3RhY2suY2x1YjEjMCEGCSqGSIb3DQEJARYUYWRtaW5AZnVsbHN0 +YWNrLmNsdWIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAK37o164k/9lWILN +5W1tJOm3fZ23rQR+aISs/XYm+JxWfpi362lYsuTjTwkNI8vtZoBDHk44Sn7RCc8x +dlK+0CPIv7Nhz3vFrUQN+YV7Tn9oNPHq8pxFekH3ioez5WD6NL/h45uX2yfg99O3 +A7SeP1ZRffki6DbcNPvqR/RgcZOLAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZI +AYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQW +BBS9bRm4cAT9HZAN0u1sD1iu3L6P7zAfBgNVHSMEGDAWgBSs5/eO2gIGSLXnekU4 +XBMSmSFm6jANBgkqhkiG9w0BAQsFAAOCAQEAOjL1qIfvXi7MP/gQTYql3L7gO7N4 +Q7XlGT157YJdxD2cWsP/VMc8qOyyp3941I5BC7HQgQbtYbUV4kx8mYLxk8Eajw16 +1K5pL0pgSEy+OuNALu1NXJAAH1ES9vk0XqxM6LSh6S0Wr5K+ACSKAOKjmCpBzSpb +IW3lVfRU3xHYnB3hnoLn9d11aokTgHU2jTg/O5aiXsI/v/BWjlSTmQ+CkDhWR4Sc ++A1dRdMfxitJX94rt2JuGEeOjbQ9bmR0hvNVrxMXmi1naq/Y2mgJT+oUaURKrzRj +ziKf6Q8hFIh8i77p/LPtGdRnRofXj+PBB9n44fZdoyzkPWFDLVctaCASrQ== +-----END CERTIFICATE----- diff --git a/src/test/resources/x509/c6.crt b/src/test/resources/x509/c6.crt new file mode 100644 index 0000000..0e15c6c --- /dev/null +++ b/src/test/resources/x509/c6.crt @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAm6gAwIBAgIFEAQoJFEwDAYIKoEcz1UBg3UFADBcMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRswGQYDVQQDDBJDRkNBIFRFU1QgU00yIE9DQTEwHhcNMTcwMzA3MDQwMTQ3 +WhcNMTgwMzA3MDQwMTQ3WjBwMQswCQYDVQQGEwJDTjESMBAGA1UECgwJQ0ZDQSBP +Q0ExMQ0wCwYDVQQLDARZQ0NBMRUwEwYDVQQLDAxJbmRpdmlkdWFsLTIxJzAlBgNV +BAMMHllDQ0FA6buE6YeR5Lqk5piT5omAQFpodWFuZ2pAMTBZMBMGByqGSM49AgEG +CCqBHM9VAYItA0IABDYpfpT8Mh5kZ+PxwFYkq4xrsAqWtwFwUhd49383cskXrksk +syXxTJHsaO0zicS9wPJjMPKcKBEaNcvR/qjDGhijggEFMIIBATAfBgNVHSMEGDAW +gBRr/hjaj0I6prhtsy6Igzo0osEw4TBIBgNVHSAEQTA/MD0GCGCBHIbvKgEBMDEw +LwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2ZjYS5jb20uY24vdXMvdXMtMTQuaHRt +MAwGA1UdEwEB/wQCMAAwOAYDVR0fBDEwLzAtoCugKYYnaHR0cDovL3VjcmwuY2Zj +YS5jb20uY24vU00yL2NybDEwODEuY3JsMA4GA1UdDwEB/wQEAwIGwDAdBgNVHQ4E +FgQUQpDr0hamRXBP3GPxltNxJUxQkqAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsG +AQUFBwMEMAwGCCqBHM9VAYN1BQADRwAwRAIgAr3J2p/GIP5Jnc4Ns9IXZWCuqDay +Ql920AXKZuPI8AMCIBQDDqp49VI9S69icZY+U90jPts4BNYEHiPE+q0/uw0S +-----END CERTIFICATE-----