From 478c36fbff8026a78c8798597e377bf82ed76705 Mon Sep 17 00:00:00 2001 From: Cheney Date: Thu, 21 Nov 2024 17:30:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8C=E6=AD=A5=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 112233.bin | Bin 0 -> 1979 bytes certificate.pem | Bin 0 -> 239 bytes gmhelper.iml | 34 ++ js/mac.js | 166 +++++++++ js/package-lock.json | 28 ++ js/package.json | 14 + js/sm4.js | 318 ++++++++++++++++++ js/test.js | 42 +++ mystore.p12 | Bin 0 -> 3339 bytes openssl/CN00000001.cer | 3 + openssl/IDCTEST4XXX-new.p12 | Bin 0 -> 1453 bytes ... Class Enterprise Subscriber CA - Test.cer | 30 ++ ...n Zhen iTrusChina Class Root CA - Test.cer | 23 ++ openssl/cmtp.cer | 56 +++ openssl/cmtp.p12 | Bin 0 -> 4341 bytes openssl/env.cmd | 1 + openssl/sandbox.cer | 18 + openssl/sandbox.p12 | Bin 0 -> 968 bytes openssl/sandbox.pem | 23 ++ openssl/user.p12 | Bin 0 -> 976 bytes private_key.pem | Bin 0 -> 150 bytes protected_file.p7m | Bin 0 -> 315 bytes public_key.pem | Bin 0 -> 91 bytes root.p12 | Bin 0 -> 3291 bytes sHSM.iml | 8 + .../shsm/logiclayer/SYDSignerBuilder.java | 29 ++ .../chakracoin/shsm/util/TripleDESUtil.java | 83 +++++ src/test/java/Base64De.java | 17 + src/test/java/FileUtil.java | 18 + src/test/java/OpenCIPS.java | 60 ++++ src/test/java/RSA.java | 253 ++++++++++++++ src/test/java/RSAEncryptionExample.java | 51 +++ src/test/java/Renzheng.java | 145 ++++++++ src/test/java/Ret.java | 32 ++ src/test/java/SM2VerificationUtil.java | 26 ++ src/test/java/Test.java | 39 +++ .../com/chakracoin/shsm/cert/QPublicKey.java | 84 +++++ .../chakracoin/shsm/cert/SimplePublicKey.java | 47 +++ src/test/java/com/chakracoin/shsm/shsm.iml | 11 + .../chakracoin/shsm/test/CmsApplication.java | 197 +++++++++++ .../com/chakracoin/shsm/test/Keytools.java | 58 ++++ .../com/chakracoin/shsm/test/PBKDF2Tool.java | 148 ++++++++ .../com/chakracoin/shsm/test/PKCS7Test.java | 162 +++++++++ .../com/chakracoin/shsm/test/PKCS7Util.java | 233 +++++++++++++ .../com/chakracoin/shsm/test/PKKDF2Test.java | 17 + .../chakracoin/shsm/test/SM2KeyUtilTest.java | 67 ++++ src/test/java/com/chakracoin/shsm/test/t.java | 79 +++++ .../java/com/chakracoin/shsm/test/t2.java | 17 + src/test/java/example/SM2Kit.java | 136 ++++++++ src/test/java/example/SM2Result.java | 25 ++ .../java/org/bouncycastle/cms/SydCmsUtil.java | 144 ++++++++ .../java/p12/StoreRSAKeyPairInPKCS12.java | 74 ++++ src/test/resources/dm/dm1.p7 | 1 + src/test/resources/dm/dm2.p7 | 1 + src/test/resources/x509/c3.crt | 3 + src/test/resources/x509/c4.crt | 3 + src/test/resources/x509/c6.crt | 17 + src/test/resources/x509/c7.crt | 3 + 58 files changed, 3044 insertions(+) create mode 100644 112233.bin create mode 100644 certificate.pem create mode 100644 gmhelper.iml create mode 100644 js/mac.js create mode 100644 js/package-lock.json create mode 100644 js/package.json create mode 100644 js/sm4.js create mode 100644 js/test.js create mode 100644 mystore.p12 create mode 100644 openssl/CN00000001.cer create mode 100644 openssl/IDCTEST4XXX-new.p12 create mode 100644 openssl/ca/Shen Zhen iTrusChina Class Enterprise Subscriber CA - Test.cer create mode 100644 openssl/ca/Shen Zhen iTrusChina Class Root CA - Test.cer create mode 100644 openssl/cmtp.cer create mode 100644 openssl/cmtp.p12 create mode 100644 openssl/env.cmd create mode 100644 openssl/sandbox.cer create mode 100644 openssl/sandbox.p12 create mode 100644 openssl/sandbox.pem create mode 100644 openssl/user.p12 create mode 100644 private_key.pem create mode 100644 protected_file.p7m create mode 100644 public_key.pem create mode 100644 root.p12 create mode 100644 sHSM.iml create mode 100644 src/main/java/com/chakracoin/shsm/logiclayer/SYDSignerBuilder.java create mode 100644 src/main/java/com/chakracoin/shsm/util/TripleDESUtil.java create mode 100644 src/test/java/Base64De.java create mode 100644 src/test/java/FileUtil.java create mode 100644 src/test/java/OpenCIPS.java create mode 100644 src/test/java/RSA.java create mode 100644 src/test/java/RSAEncryptionExample.java create mode 100644 src/test/java/Renzheng.java create mode 100644 src/test/java/Ret.java create mode 100644 src/test/java/SM2VerificationUtil.java create mode 100644 src/test/java/Test.java create mode 100644 src/test/java/com/chakracoin/shsm/cert/QPublicKey.java create mode 100644 src/test/java/com/chakracoin/shsm/cert/SimplePublicKey.java create mode 100644 src/test/java/com/chakracoin/shsm/shsm.iml create mode 100644 src/test/java/com/chakracoin/shsm/test/CmsApplication.java create mode 100644 src/test/java/com/chakracoin/shsm/test/Keytools.java create mode 100644 src/test/java/com/chakracoin/shsm/test/PBKDF2Tool.java create mode 100644 src/test/java/com/chakracoin/shsm/test/PKCS7Test.java create mode 100644 src/test/java/com/chakracoin/shsm/test/PKCS7Util.java create mode 100644 src/test/java/com/chakracoin/shsm/test/PKKDF2Test.java create mode 100644 src/test/java/com/chakracoin/shsm/test/SM2KeyUtilTest.java create mode 100644 src/test/java/com/chakracoin/shsm/test/t.java create mode 100644 src/test/java/com/chakracoin/shsm/test/t2.java create mode 100644 src/test/java/example/SM2Kit.java create mode 100644 src/test/java/example/SM2Result.java create mode 100644 src/test/java/org/bouncycastle/cms/SydCmsUtil.java create mode 100644 src/test/java/p12/StoreRSAKeyPairInPKCS12.java create mode 100644 src/test/resources/dm/dm1.p7 create mode 100644 src/test/resources/dm/dm2.p7 create mode 100644 src/test/resources/x509/c3.crt create mode 100644 src/test/resources/x509/c4.crt create mode 100644 src/test/resources/x509/c6.crt create mode 100644 src/test/resources/x509/c7.crt diff --git a/112233.bin b/112233.bin new file mode 100644 index 0000000000000000000000000000000000000000..13840e42f9645a2dc618eaa4ed51dc0a77b9c49e GIT binary patch literal 1979 zcmXqLV&BfjsnzDu_MMlJooPW6`wD|5_9aY=jD`#b+z1&)piGZJ6O)KR6XW&;%uI|- zOk5E>x~z6*TCdyfHsE37&}x)9AIjKV%F196YshWD$;KSY!Y0h*>}P0Tpa$p2=jK6F0&H@%T|knciwUCe8$RSy!J@l?hgf#Ii9OGv6r(L$x8lZtnz8Nz4EWO z|4WUZkJ;ou>vd21{IKzfqk8YoA5677PW8I&UmR-?Z6FWyxvVmagn?Lt$krPZ@?$>S zFus($w{Fwn-edkkRf)i`1}YF{VKrc8Wc&||BOs5Tg#{QTYzDF*4j+pc3oe~VvBd1j zVBp52$S~ncMoe4q%Rd!j*ZhOqoQ`bJdTnvd+jsFB{eO>tbvbMYDG{9-?40sm_n@Ro z)*DCVCyzRw<<};-TWY?zZS89ZbaNAvFECwvf~JcUmFo?Ac{Dz+Wv6?(Ff=kWGBO2W z12a&%FfuSVGKO*uVkk|P(gu>i00t&YAw;qSrAdEhM?(YL$-;O?1ZVE^i089+nOboQ z1x`Ej<=v4BnlLOtX+fUF&_LfncY*c-%{KLnl9B=|eSITC13hySJrg56WBroU;*z4| zM17zy^plHn4E2Bnt|XQHPvTa;lhv{vxtsMmnypM09W;1|8o|u&3dtic@5x^lXXF|*G0OuJ)e%U7VigGOG;T+=ipG%%Dq@U*<%x*_F!>l51CtVvYX;{U zM4=`negj@m!r(RR?`b6dTt|EB_XFWdg*Pu@@C z3}zPN{CLv+0{<-2+)0Y$33l=vq76S8WF1T<879mUq3Qle{dlr$RcJS(uCr%c9sJx7{!rN7xNFK0&D%Rx<|DwD{G!7?m3^OIZdTigZ(N* zS`}mz%vH=xa26vyyMBNG!NqX8EihgPG^`B28@QUeA9IdNViV*^V=Ljy|#Gb58IAlC%Q zHGpz~Dk2Sp+1Rz(JkHrNF~YPq=`uSpurSseozZ-~*!GZF#gXINST}gosr$@osh@rI zd$s-=!Rc1(E=O=ks&tn|+_>X1^>1$1nunDd;oa9}u3Ol!^Y_>18<3sC?7?8*%B09J z@4%*Iv#wvLy*=ejm|bsok$+~r<)rE5E4VfI;%=^K-pZul5KzxK(}-hZ)!x?|SyoA# V=;fFTo87$I>daeK;kkb^I{;-SR-^y` literal 0 HcmV?d00001 diff --git a/gmhelper.iml b/gmhelper.iml new file mode 100644 index 0000000..53519aa --- /dev/null +++ b/gmhelper.iml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/js/mac.js b/js/mac.js new file mode 100644 index 0000000..2b2fa6e --- /dev/null +++ b/js/mac.js @@ -0,0 +1,166 @@ +var CryptoJS = require("crypto-js"); +var fHEX = require("crypto-js/format-hex"); + +function enc(text, key){ + var encrypt = CryptoJS.TripleDES.encrypt(text, key, { + mode: CryptoJS.mode.ECB, // CBC模式 + // mode: CryptoJS.mode.ECB, // ECB模式 + padding: CryptoJS.pad.NoPadding // padding处理 + } + ); + var encryptData = encrypt.toString(fHEX); // 加密完成后,转换成字符串 + // console.log(encryptData) + return encryptData + +} + +/** + * int 转 byte + * @param i + */ +function intToByte(i) { + var b = i & 0xFF; + var c = 0; + if (b >= 128) { + c = b % 128; + c = -1 * (128 - c); + } else { + c = b; + } + return c; +} + +function stringToHex(str){ + var val = ""; + for (var i = 0; i < str.length; i++) { + var v = str.charCodeAt(i).toString(16); + if ( v.length < 2 ) { + v = "0" + v; + } + val += v; + } + return val +} +function toHex(d) { return ("0"+(Number(d).toString(16))).slice(-2).toUpperCase() } + +function mac( hex ) { + if ( ! /^([A-Fa-f0-9][A-Fa-f0-9])+$/.test( hex ) ) { + throw "hex 格式错误" + } + var checkNum = intToByte(0); + var arrBytes = new Array(); + for ( var i = 0 ; i < hex.length; i+=2 ) { + var v = intToByte(parseInt(hex[i] + hex[i+1], 16)) + arrBytes.push( v ) + checkNum = checkNum ^ v; + } + + return toHex( checkNum & 0xFF ) +} + +function xor(d1, d2, d3) { + if ( 32 !== d1.length || 32 !== d2.length || 32 !== d3.length ) { + throw "输入格式错误" + } + + var a1 = hexToBytes(d1); + var a2 = hexToBytes(d2); + var a3 = hexToBytes(d3); + + var data = []; + for ( var i = 0; i < 16 ; i++){ + data[ i ] = a1[ i ] ^ a2[ i ] ^ a3[ i ] + } + + return bytesToHex( data ) +} + +// Des3 +// npm i crypto-js +function hexToBytes(hex) { + for (var bytes = [], c = 0; c < hex.length; c += 2) + bytes.push(parseInt(hex.substr(c, 2), 16)); + return bytes; +} + +function bytesToHex(bytes) { + for (var hex = [], i = 0; i < bytes.length; i++) { + hex.push((bytes[i] >>> 4).toString(16)); + hex.push((bytes[i] & 0xF).toString(16)); + } + return hex.join(""); +} + +const des = { + CalDES: function (a1, a2) { + a1 = "00000000000000000000000000000000" + a2 = bytesToHex(a2) + // var data = []; + // for ( var i = 0; i < 16 ; i++){ + // data[ i ] = a1[ i ] ^ a2[ i ] + // } + + // return bytesToHex( data ) + + var text = CryptoJS.enc.Hex.parse(a1); + var key = CryptoJS.enc.Hex.parse(a2); + return enc(text, key); + + } +} + +const sm4 = require('./sm4.js') + + +// 校验值 +function checkValue(p1,p2,p3) { + var keyPlaintext = xor(p1, p2, p3) + // 废弃 des 算法 + // var ret = des.CalDES(hexToBytes("0000000000000000"), hexToBytes(keyPlaintext)) + var ret = sm4.SM4CryptECB("00000000000000000000000000000000", 1, keyPlaintext) + const checkValue = ret.slice(0, 8) + return { checkValue, ret, keyPlaintext } +} + +// 校验值 +function checkValueKey(l1,l2,l3, protectKey) { + const key = xor(l1,l2,l3) + var ret = sm4.SM4CryptECB("00000000000000000000000000000000", 1, key) + const checkValue = ret.slice(0, 8) + const keyCiphertext = sm4.SM4CryptECB(key, 1 , protectKey) + return { keyCiphertext, checkValue, ret} +} + +function decryptionKey(keyCiphertext, checkValue) { + const keyPlaintext = sm4.SM4CryptECB(keyCiphertext, 0, checkValue) + let ret = kcv( keyCiphertext ) + const checkData = ret.slice(0, 8) + return { keyPlaintext, checkData } +} + +/** + * 计算密钥校验值 + * key 是密钥 16 字节的 HEX 格式。 + */ +function kcv( key ){ + const v = sm4.SM4CryptECB("00000000000000000000000000000000", 1, key) + return v; +} + +function decryptKey(value, key){ + const v = sm4.SM4CryptECB(value, 0, key) + return v; +} + +module.exports = { xor, kcv, decryptKey, checkValue, checkValueKey, decryptionKey } + +// const tripledes = require("crypto-js/tripledes"); +// +// var value = "123";CryptoJS.enc.Hex.parse("0000000000000000"); +// var key = "12345678123456781234567812345678"; CryptoJS.enc.Hex.parse("12345678123456781234567812345678"); +// +// var encrypted = tripledes.encrypt(value , key); +// var decrypted = tripledes.decrypt(encrypted, key); +// +// console.log( "encrypted", encrypted.toString('hex') ) +// console.log( "decrypted", decrypted ) diff --git a/js/package-lock.json b/js/package-lock.json new file mode 100644 index 0000000..cb1eeb2 --- /dev/null +++ b/js/package-lock.json @@ -0,0 +1,28 @@ +{ + "name": "js", + "version": "1.0.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "js", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "crypto-js": "^4.1.1" + } + }, + "node_modules/crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + } + }, + "dependencies": { + "crypto-js": { + "version": "4.1.1", + "resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.1.1.tgz", + "integrity": "sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==" + } + } +} diff --git a/js/package.json b/js/package.json new file mode 100644 index 0000000..162d0f1 --- /dev/null +++ b/js/package.json @@ -0,0 +1,14 @@ +{ + "name": "js", + "version": "1.0.0", + "description": "", + "main": "test.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "crypto-js": "^4.1.1" + } +} diff --git a/js/sm4.js b/js/sm4.js new file mode 100644 index 0000000..effeb2a --- /dev/null +++ b/js/sm4.js @@ -0,0 +1,318 @@ +var SM4 = {}; + +(function () { + var SM4_ENCRYPT = 1 + var SM4_DECRYPT = 0 + + function sm4_context() { + this.mode = 0; + this.sk = [] + } + + function GET_ULONG_BE(n, b, i) { + return (b[i] << 24) | (b[i + 1] << 16) | (b[i + 2]) << 8 | (b[i + 3]) + } + + function PUT_ULONG_BE(n, b, i) { + b[i] = n >>> 24 + b[i + 1] = n >>> 16 + b[i + 2] = n >>> 8 + b[i + 3] = n + } + + function ROTL(x, n) { + var a = (x & 0xFFFFFFFF) << n + var b = x >>> (32 - n) + + return a | b + } + + var SboxTable = [ + [0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05], + [0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99], + [0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62], + [0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6], + [0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8], + [0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35], + [0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87], + [0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e], + [0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1], + [0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3], + [0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f], + [0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51], + [0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8], + [0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0], + [0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84], + [0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48] + ] + + var FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]; + var CK = [ + 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, + 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, + 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, + 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, + 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, + 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, + 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, + 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 + ] + + function sm4Sbox(n) { + var l = n >>> 4 + var r = n % 16 + return SboxTable[l][r] + } + + function sm4Lt(ka) { + var bb = 0; + var c = 0; + var a = new Uint8Array(4); + var b = new Array(4); + PUT_ULONG_BE(ka, a, 0) + b[0] = sm4Sbox(a[0]) + b[1] = sm4Sbox(a[1]) + b[2] = sm4Sbox(a[2]) + b[3] = sm4Sbox(a[3]) + bb = GET_ULONG_BE(bb, b, 0) + + c = bb ^ (ROTL(bb, 2)) ^ (ROTL(bb, 10)) ^ (ROTL(bb, 18)) ^ (ROTL(bb, 24)) + return c; + } + + function sm4F(x0, x1, x2, x3, rk) { + return (x0 ^ sm4Lt(x1 ^ x2 ^ x3 ^ rk)) + } + + function sm4CalciRK(ka) { + var bb = 0; + var rk = 0; + var a = new Uint8Array(4); + var b = new Array(4); + PUT_ULONG_BE(ka, a, 0) + b[0] = sm4Sbox(a[0]); + b[1] = sm4Sbox(a[1]); + b[2] = sm4Sbox(a[2]); + b[3] = sm4Sbox(a[3]); + bb = GET_ULONG_BE(bb, b, 0) + + rk = bb ^ (ROTL(bb, 13)) ^ (ROTL(bb, 23)) + + return rk; + } + + function sm4_setkey(SK, key) { + var MK = new Array(4); + var k = new Array(36); + var i = 0; + MK[0] = GET_ULONG_BE(MK[0], key, 0); + MK[1] = GET_ULONG_BE(MK[1], key, 4); + MK[2] = GET_ULONG_BE(MK[2], key, 8); + MK[3] = GET_ULONG_BE(MK[3], key, 12); + + k[0] = MK[0] ^ FK[0] + k[1] = MK[1] ^ FK[1] + k[2] = MK[2] ^ FK[2] + k[3] = MK[3] ^ FK[3] + + for (; i < 32; i++) { + k[i + 4] = k[i] ^ (sm4CalciRK(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ CK[i])) + SK[i] = k[i + 4]; + } + } + + function sm4_one_round(sk, input, output) { + var i = 0; + var ulbuf = new Array(36); + + ulbuf[0] = GET_ULONG_BE(ulbuf[0], input, 0) + ulbuf[1] = GET_ULONG_BE(ulbuf[1], input, 4) + ulbuf[2] = GET_ULONG_BE(ulbuf[2], input, 8) + ulbuf[3] = GET_ULONG_BE(ulbuf[3], input, 12) + while (i < 32) { + ulbuf[i + 4] = sm4F(ulbuf[i], ulbuf[i + 1], ulbuf[i + 2], ulbuf[i + 3], sk[i]); + i++; + } + + PUT_ULONG_BE(ulbuf[35], output, 0); + PUT_ULONG_BE(ulbuf[34], output, 4); + PUT_ULONG_BE(ulbuf[33], output, 8); + PUT_ULONG_BE(ulbuf[32], output, 12); + } + + function sm4_setkey_enc(ctx, key) { + ctx.mode = SM4_ENCRYPT; + sm4_setkey(ctx.sk, key); + } + + function sm4_setkey_dec(ctx, key) { + var i, j; + ctx.mode = SM4_ENCRYPT; + sm4_setkey(ctx.sk, key); + for (i = 0; i < 16; i++) { + j = ctx.sk[31 - i] + ctx.sk[31 - i] = ctx.sk[i] + ctx.sk[i] = j + } + } + + function sm4_crypt_ecb(ctx, mode, length, input, output) { + var index = 0; + while (length > 0) { + var oneInput = input.slice(index, index + 16) + var oneOutput = new Uint8Array(16) + sm4_one_round(ctx.sk, oneInput, oneOutput); + + for (var i = 0; i < 16; i++) { + output[index + i] = oneOutput[i] + } + index += 16; + length -= 16; + } + } + + function sm4_crypt_cbc(ctx, mode, length, iv, input, output) { + var i; + var temp = new Array(16); + var index = 0; + + if (mode == SM4_ENCRYPT) { + while (length > 0) { + var oneInput = input.slice(index, index + 16) + var oneOutput = new Array(16) + for (i = 0; i < 16; i++) { + oneOutput[i] = oneInput[i] ^ iv[i] + } + + sm4_one_round(ctx.sk, oneOutput, oneOutput); + + for (i = 0; i < 16; i++) { + iv[i] = oneOutput[i] + output[index + i] = oneOutput[i] + } + + index += 16; + length -= 16; + } + } else /* SM4_DECRYPT */ { + while (length > 0) { + var oneInput = input.slice(index, index + 16) + var oneOutput = new Array(16) + index += 16; + for (i = 0; i < 16; i++) { + temp[i] = oneInput[i] + } + + sm4_one_round(ctx.sk, oneInput, oneOutput); + + for (i = 0; i < 16; i++) { + oneOutput[i] = oneOutput[i] ^ iv[i] + output[index + i] = oneOutput[i] + } + + for (i = 0; i < 16; i++) { + iv[i] = temp[i] + } + + index += 16; + length -= 16; + } + } + } + + function strfix(str, len) { + var length = len - str.length + while (length-- > 0) { + str = "0" + str + } + return str + } + + function HEXStrXOR(str1, str2) { + var buf1 = hex2Array(str1) + var buf2 = hex2Array(str2) + + var result = '' + for (var i = 0; i < 16; i++) { + result += strfix((buf1[i] ^ buf2[i]).toString(16).toUpperCase(), 2) + } + + return result + } + + function hex2Array(str) { + var len = str.length / 2, + substr = '', + result = new Array(len); + for (var i = 0; i < len; i++) { + substr = str.slice(2 * i, 2 * (i + 1)) + result[i] = parseInt(substr, 16) || 0 + } + return result + } + + SM4.SM4CryptECB = function (szData, sCryptFlag, szSM4Key) { + if (szSM4Key.length !== 32) { + console.log("传入密钥[" + szSM4Key + "]长度不为32位"); + return ""; + } + var len = szData.length + var count = len % 32 + if(count !== 0) { + count = 32 - count + len += count + while (count --) { + szData += '0' + } + } + + var ctx = new sm4_context() + var lpbKey = hex2Array(szSM4Key) + if (sCryptFlag === SM4_ENCRYPT) { + sm4_setkey_enc(ctx, lpbKey); //加密 + } else { + sm4_setkey_dec(ctx, lpbKey); //解密 + } + + var lpbData = hex2Array(szData) + var pbyCryptResult = new Array(len / 2) + sm4_crypt_ecb(ctx, sCryptFlag, len / 2, lpbData, pbyCryptResult) + var szResult = '' + for (var i = 0; i < len / 2; i++) { + szResult += strfix(pbyCryptResult[i].toString(16), 2).toUpperCase() + } + + return szResult; + } + + SM4.SM4MACGenerated = function (szData, szSM4Key) { + if (szSM4Key.length !== 32) { + console.log("传入密钥[" + szSM4Key + "]长度不为32位"); + return ""; + } + var len = szData.length + var count = Math.floor(len / 32) + if (len % 32 !== 0) { + count += 1; + var dvalue = count * 32 - len + while(dvalue--) szData += '0'; + len = count * 32 + } + + var szResult = '', macString = ''; + for (var i = 0; i < count; i++) { + macString = szData.slice(32 * i, 32 * (i + 1)) + if (i > 0) { + macString = HEXStrXOR(macString, szResult); + } + szResult = SM4.SM4CryptECB(macString, 1, szSM4Key); + } + return szResult + } +})() + +try { + module.exports = SM4 +} catch (error) { + +} diff --git a/js/test.js b/js/test.js new file mode 100644 index 0000000..09efbc5 --- /dev/null +++ b/js/test.js @@ -0,0 +1,42 @@ +const mac = require("./mac") + + + +function case1(){ + console.log("case1") + let v1 = "11111111111111111111111111111111"; + let v2 = "22222222222222222222222222222222"; + let v3 = "33333333333333333333333333333333"; + + let kek_kcv = "9F1F7BFF"; + let main_key_en = "9F1F7BFF6F5511384D9430531E538FD3"; + let main_key_kcv = "9F1F7BFF"; + + let kek = mac.xor(v1, v2, v3); + console.log("kek=" + kek) + console.log("kcv=" + mac.kcv(kek)) + let main_key = mac.decryptKey(main_key_en, kek); + console.log("main_key=" + main_key) + +} + +function case2(){ + console.log("case2") + let v1 = "33333333333333333333333333333333"; + let v2 = "33333333333333333333333333333333"; + let v3 = "33333333333333333333333333333333"; + + let kek_kcv = "A43FDDA6"; + let main_key_en = "9F1F7BFF6F5511384D9430531E538FD3"; + let main_key_kcv = "FOA71CB9"; + + let kek = mac.xor(v1, v2, v3); + console.log("kek=" + kek) + console.log("kcv=" + mac.kcv(kek)) + let main_key = mac.decryptKey(main_key_en, kek); + console.log("main_key=" + main_key) + console.log("kcv=" + mac.kcv(main_key)) +} + +case1() +case2() diff --git a/mystore.p12 b/mystore.p12 new file mode 100644 index 0000000000000000000000000000000000000000..f3fcc3fa29287d193648a79b9d8334a37763adbf GIT binary patch literal 3339 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 literal 0 HcmV?d00001 diff --git a/openssl/ca/Shen Zhen iTrusChina Class Enterprise Subscriber CA - Test.cer b/openssl/ca/Shen Zhen iTrusChina Class Enterprise Subscriber CA - Test.cer new file mode 100644 index 0000000..30cb664 --- /dev/null +++ b/openssl/ca/Shen Zhen iTrusChina Class Enterprise Subscriber CA - Test.cer @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIUZJKPAoJ57yWXXaaMX+WMpunlTv8wDQYJKoZIhvcNAQEF +BQAweTEzMDEGA1UEAwwqU2hlbiBaaGVuIGlUcnVzQ2hpbmEgQ2xhc3MgIFJvb3Qg +Q0EgLSBUZXN0MRgwFgYDVQQLDA/mtYvor5Xpg6jor5XnlKgxGzAZBgNVBAoMEuWk +qeivmuWuieS/oeivleeUqDELMAkGA1UEBhMCQ04wHhcNMTYwNTE2MTgxNDA2WhcN +MzYwNTExMTgxNDA2WjCBiTFDMEEGA1UEAww6U2hlbiBaaGVuIGlUcnVzQ2hpbmEg +Q2xhc3MgRW50ZXJwcmlzZSBTdWJzY3JpYmVyIENBIC0gVGVzdDEYMBYGA1UECwwP +5rWL6K+V6YOo6K+V55SoMRswGQYDVQQKDBLlpKnor5rlronkv6Hor5XnlKgxCzAJ +BgNVBAYTAkNOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkFOpER3o +/8s3w1N/JFQa+fetEzdHOp05YqAZR9UnwwUAomcwI6fDF8N4rFW388wEv2X0810P +wCcNOyq+ep6s3gpoHXD2TRLkzn6UwNiIVcaIo9eo/wkv5F2VAglhjKagnYbaemWN +6aDi9r4GqaK91JbtgIUyBFrZoMaAZDhz2GhnWIWv0So1RsBDlZPuaEDtVvo4uFlO +0TqUvQyQLMy//8wBKtOo2PLM6ScsSnwuk+zNjvC0gSU1lcxWkX4TtYr0EgACT06K +58o+RCQ/U3jEuU1bcWs4Y0YTeEs/WaGn/cxhxosgYr15qZTd4Z/nTqeUYCc8JEe2 +18638g7Irj6GeQIDAQABo4IBhDCCAYAwHQYDVR0OBBYEFMgyHkARfkHUu1UBr8xH +GkI1RqvvMB8GA1UdIwQYMBaAFMm7ezHzbz8qxHmwZvn0VvWZPOheMAwGA1UdEwQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMEoGCCsGAQUFBwEBBD4wPDA6BggrBgEFBQcw +AYYuaHR0cDovL1lvdXJfU2VydmVyX05hbWU6UG9ydC9Ub3BDQS9sb2RwX0Jhc2VE +TjCBggYIKwYBBQUHAQsEdjB0MHIGCCsGAQUFBzAFhmZodHRwOi8vWW91cl9TZXJ2 +ZXJfTmFtZTpQb3J0L1RvcENBL3VzZXJFbnJvbGwvY2FDZXJ0P2NlcnRTZXJpYWxO +dW1iZXI9NDhmZTRmYWVkNzNmYmQyNDBlNGU5MDEwMzI3NWY3YWYwTwYDVR0fBEgw +RjBEoEKgQIY+UG9ydC9Ub3BDQS9wdWJsaWMvaXRydXNjcmw/Q0E9NDhmZTRmYWVk +NzNmYmQyNDBlNGU5MDEwMzI3NWY3YWYwDQYJKoZIhvcNAQEFBQADggEBAEIFs207 ++YRDggj3RFHYBKdJyA2SgG8l5tVsRR+J6n5WlLqIF6/389bmR8vXGwhahEo9vYS2 +uq5GGZqLYBdOUv8D+qlfqXOoznNCkdSrIs36cVCDepkn5uprlmMA7mYCifIeSyKb +nN+q03fm0uXNAQsGnBuD7DnXGyHIWjpfFwqm0n+bULPVJh1YKGu/p2XgQ7ML47Z3 +wZRuNLkM7ZxxokfeNl+q15nyYUUOFsfpTM/4v5I/OSj75gLA6WRc3rTU3oZgGQC3 +ncFASt+Oe5kfOFb9Owk/MNucE9plAGbOXRzvrgWdbMWswQwgjILQXU+bt53D5YV4 +Sib5RpDadrxfES0= +-----END CERTIFICATE----- diff --git a/openssl/ca/Shen Zhen iTrusChina Class Root CA - Test.cer b/openssl/ca/Shen Zhen iTrusChina Class Root CA - Test.cer new file mode 100644 index 0000000..8c81c25 --- /dev/null +++ b/openssl/ca/Shen Zhen iTrusChina Class Root CA - Test.cer @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID4zCCAsugAwIBAgIUfxbPPiiOLkYXpYBOHNXSeIjWC4gwDQYJKoZIhvcNAQEF +BQAweTEzMDEGA1UEAwwqU2hlbiBaaGVuIGlUcnVzQ2hpbmEgQ2xhc3MgIFJvb3Qg +Q0EgLSBUZXN0MRgwFgYDVQQLDA/mtYvor5Xpg6jor5XnlKgxGzAZBgNVBAoMEuWk +qeivmuWuieS/oeivleeUqDELMAkGA1UEBhMCQ04wHhcNMTYwNTE2MTgxMjAyWhcN +MzYwNTExMTgxMjAyWjB5MTMwMQYDVQQDDCpTaGVuIFpoZW4gaVRydXNDaGluYSBD +bGFzcyAgUm9vdCBDQSAtIFRlc3QxGDAWBgNVBAsMD+a1i+ivlemDqOivleeUqDEb +MBkGA1UECgwS5aSp6K+a5a6J5L+h6K+V55SoMQswCQYDVQQGEwJDTjCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAIoRQWN2rIWO2HRlbwM0L9OtkjrLVPCi +9XH2qKFoaVbBv1ACSTw7LJluk4JlWBuiWsjhDsRNTKtsPjLpn95U2aXL4OweJfC0 +AFl6fspUQMTWb5WTvWA1Ipp/prA/Gsl/HDMDmDlcwVpP6dFN1y/PcVAEL34tJl7b +h9MTYaCBrfXA7J6YUyM34vn3pG+9MUD7O51dTvGct2oDBbhvziDS1Z+8Anaq7Rvu +ktCOiOxaYNGdSOv4SWxkUHxgHN0L3ZdgJq19aM2cnwi51gKiNV+ftIByqokfKedI +4I65OgabpLwnthQVOk75TL2UesHjcNcRiHiUlXixla8CiKl5PorfznsCAwEAAaNj +MGEwHQYDVR0OBBYEFMm7ezHzbz8qxHmwZvn0VvWZPOheMB8GA1UdIwQYMBaAFMm7 +ezHzbz8qxHmwZvn0VvWZPOheMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQA+o1NydG0vpBWu4flgEPsXFOMfhum5mFv2 +/RX+pwiq9QpwQ7gK8x8Z5o30XdyPeCtbUdcbfFhyk+j41cxSeXXBBVhi+GHGE6V2 +6K+hcprpPUgGDIbnhe2fLQjlau0rjF+PZcAGOUKixpyBby+dQTX/3MYjyM0IfuO5 +/2xIl2/NyLblSHkmhw6VmsXarAZM1vcHMmR4/SQEVAhupIyYAHhDlC4Tj0tOkpph +oPiN+qCDdLKmLZG/7LcCzFfk5gMAliBaO9rtUv8txqeUq3j9OYyccouezRqXS0QG +Ryz+xr6/shGN3X2ocj7NUI9IgrAWZX9n2Qhj6dQNgczDclkD2Tuw +-----END CERTIFICATE----- diff --git a/openssl/cmtp.cer b/openssl/cmtp.cer new file mode 100644 index 0000000..57586ed --- /dev/null +++ b/openssl/cmtp.cer @@ -0,0 +1,56 @@ +-----BEGIN CERTIFICATE----- +MIID4zCCAsugAwIBAgIUfxbPPiiOLkYXpYBOHNXSeIjWC4gwDQYJKoZIhvcNAQEF +BQAweTEzMDEGA1UEAwwqU2hlbiBaaGVuIGlUcnVzQ2hpbmEgQ2xhc3MgIFJvb3Qg +Q0EgLSBUZXN0MRgwFgYDVQQLDA/mtYvor5Xpg6jor5XnlKgxGzAZBgNVBAoMEuWk +qeivmuWuieS/oeivleeUqDELMAkGA1UEBhMCQ04wHhcNMTYwNTE2MTgxMjAyWhcN +MzYwNTExMTgxMjAyWjB5MTMwMQYDVQQDDCpTaGVuIFpoZW4gaVRydXNDaGluYSBD +bGFzcyAgUm9vdCBDQSAtIFRlc3QxGDAWBgNVBAsMD+a1i+ivlemDqOivleeUqDEb +MBkGA1UECgwS5aSp6K+a5a6J5L+h6K+V55SoMQswCQYDVQQGEwJDTjCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBAIoRQWN2rIWO2HRlbwM0L9OtkjrLVPCi +9XH2qKFoaVbBv1ACSTw7LJluk4JlWBuiWsjhDsRNTKtsPjLpn95U2aXL4OweJfC0 +AFl6fspUQMTWb5WTvWA1Ipp/prA/Gsl/HDMDmDlcwVpP6dFN1y/PcVAEL34tJl7b +h9MTYaCBrfXA7J6YUyM34vn3pG+9MUD7O51dTvGct2oDBbhvziDS1Z+8Anaq7Rvu +ktCOiOxaYNGdSOv4SWxkUHxgHN0L3ZdgJq19aM2cnwi51gKiNV+ftIByqokfKedI +4I65OgabpLwnthQVOk75TL2UesHjcNcRiHiUlXixla8CiKl5PorfznsCAwEAAaNj +MGEwHQYDVR0OBBYEFMm7ezHzbz8qxHmwZvn0VvWZPOheMB8GA1UdIwQYMBaAFMm7 +ezHzbz8qxHmwZvn0VvWZPOheMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD +AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQA+o1NydG0vpBWu4flgEPsXFOMfhum5mFv2 +/RX+pwiq9QpwQ7gK8x8Z5o30XdyPeCtbUdcbfFhyk+j41cxSeXXBBVhi+GHGE6V2 +6K+hcprpPUgGDIbnhe2fLQjlau0rjF+PZcAGOUKixpyBby+dQTX/3MYjyM0IfuO5 +/2xIl2/NyLblSHkmhw6VmsXarAZM1vcHMmR4/SQEVAhupIyYAHhDlC4Tj0tOkpph +oPiN+qCDdLKmLZG/7LcCzFfk5gMAliBaO9rtUv8txqeUq3j9OYyccouezRqXS0QG +Ryz+xr6/shGN3X2ocj7NUI9IgrAWZX9n2Qhj6dQNgczDclkD2Tuw +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFFzCCA/+gAwIBAgIUZJKPAoJ57yWXXaaMX+WMpunlTv8wDQYJKoZIhvcNAQEF +BQAweTEzMDEGA1UEAwwqU2hlbiBaaGVuIGlUcnVzQ2hpbmEgQ2xhc3MgIFJvb3Qg +Q0EgLSBUZXN0MRgwFgYDVQQLDA/mtYvor5Xpg6jor5XnlKgxGzAZBgNVBAoMEuWk +qeivmuWuieS/oeivleeUqDELMAkGA1UEBhMCQ04wHhcNMTYwNTE2MTgxNDA2WhcN +MzYwNTExMTgxNDA2WjCBiTFDMEEGA1UEAww6U2hlbiBaaGVuIGlUcnVzQ2hpbmEg +Q2xhc3MgRW50ZXJwcmlzZSBTdWJzY3JpYmVyIENBIC0gVGVzdDEYMBYGA1UECwwP +5rWL6K+V6YOo6K+V55SoMRswGQYDVQQKDBLlpKnor5rlronkv6Hor5XnlKgxCzAJ +BgNVBAYTAkNOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkFOpER3o +/8s3w1N/JFQa+fetEzdHOp05YqAZR9UnwwUAomcwI6fDF8N4rFW388wEv2X0810P +wCcNOyq+ep6s3gpoHXD2TRLkzn6UwNiIVcaIo9eo/wkv5F2VAglhjKagnYbaemWN +6aDi9r4GqaK91JbtgIUyBFrZoMaAZDhz2GhnWIWv0So1RsBDlZPuaEDtVvo4uFlO +0TqUvQyQLMy//8wBKtOo2PLM6ScsSnwuk+zNjvC0gSU1lcxWkX4TtYr0EgACT06K +58o+RCQ/U3jEuU1bcWs4Y0YTeEs/WaGn/cxhxosgYr15qZTd4Z/nTqeUYCc8JEe2 +18638g7Irj6GeQIDAQABo4IBhDCCAYAwHQYDVR0OBBYEFMgyHkARfkHUu1UBr8xH +GkI1RqvvMB8GA1UdIwQYMBaAFMm7ezHzbz8qxHmwZvn0VvWZPOheMAwGA1UdEwQF +MAMBAf8wDgYDVR0PAQH/BAQDAgEGMEoGCCsGAQUFBwEBBD4wPDA6BggrBgEFBQcw +AYYuaHR0cDovL1lvdXJfU2VydmVyX05hbWU6UG9ydC9Ub3BDQS9sb2RwX0Jhc2VE +TjCBggYIKwYBBQUHAQsEdjB0MHIGCCsGAQUFBzAFhmZodHRwOi8vWW91cl9TZXJ2 +ZXJfTmFtZTpQb3J0L1RvcENBL3VzZXJFbnJvbGwvY2FDZXJ0P2NlcnRTZXJpYWxO +dW1iZXI9NDhmZTRmYWVkNzNmYmQyNDBlNGU5MDEwMzI3NWY3YWYwTwYDVR0fBEgw +RjBEoEKgQIY+UG9ydC9Ub3BDQS9wdWJsaWMvaXRydXNjcmw/Q0E9NDhmZTRmYWVk +NzNmYmQyNDBlNGU5MDEwMzI3NWY3YWYwDQYJKoZIhvcNAQEFBQADggEBAEIFs207 ++YRDggj3RFHYBKdJyA2SgG8l5tVsRR+J6n5WlLqIF6/389bmR8vXGwhahEo9vYS2 +uq5GGZqLYBdOUv8D+qlfqXOoznNCkdSrIs36cVCDepkn5uprlmMA7mYCifIeSyKb +nN+q03fm0uXNAQsGnBuD7DnXGyHIWjpfFwqm0n+bULPVJh1YKGu/p2XgQ7ML47Z3 +wZRuNLkM7ZxxokfeNl+q15nyYUUOFsfpTM/4v5I/OSj75gLA6WRc3rTU3oZgGQC3 +ncFASt+Oe5kfOFb9Owk/MNucE9plAGbOXRzvrgWdbMWswQwgjILQXU+bt53D5YV4 +Sib5RpDadrxfES0= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEszCCA5ugAwIBAgIUFCWuFVNswuL5DNo84rI4C/8kGUEwDQYJKoZIhvcNAQELBQAwgYkxQzBBBgNVBAMMOlNoZW4gWmhlbiBpVHJ1c0NoaW5hIENsYXNzIEVudGVycHJpc2UgU3Vic2NyaWJlciBDQSAtIFRlc3QxGDAWBgNVBAsMD+a1i+ivlemDqOivleeUqDEbMBkGA1UECgwS5aSp6K+a5a6J5L+h6K+V55SoMQswCQYDVQQGEwJDTjAeFw0yMjExMzAwMjAxMTVaFw0yMzExMzAwMjAxMTVaMFQxDDAKBgNVBAMMA3N5ZDESMBAGA1UECwwJ5oqA5pyv6YOoMTAwLgYDVQQKDCfkuK3ljZfli5jmtYvorr7orqHnoJTnqbbpmaLmnInpmZDlhazlj7gwggEzMIHsBgcqhkjOPQIBMIHgAgEBMCwGByqGSM49AQECIQD////+/////////////////////wAAAAD//////////zBEBCD////+/////////////////////wAAAAD//////////AQgKOn6np2fXjRNWp5Lz2UJp/OXifUVq4+S3by9QU2UDpMEQQQyxK4sHxmBGV+ZBEZqOcmUj+MLv/JmC+FxWkWJM0x0x7w3NqL09necWb3O42tpIVPQqYd8xipHQALfMuUhOfCgAiEA/////v///////////////3ID32shxgUrU7v0CTnVQSMCAQEDQgAEmj2F0+wc7HPBU8G9RldToi5+YTPoNbSuoF1PKVPy4N7itwK5aNtDm9id34y+fZYi8ClEovdItZVdrzHH3HzIOqOCATQwggEwMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgbAMGoGA1UdLgRjMGEwX6BdoFuGWWh0dHA6Ly9zenRvcGNhLnN6aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT02NDkyOEYwMjgyNzlFRjI1OTc1REE2OEM1RkU1OENBNkU5RTU0RUZGMGoGA1UdHwRjMGEwX6BdoFuGWWh0dHA6Ly9zenRvcGNhLnN6aXRydXMuY29tLmNuL3B1YmxpYy9pdHJ1c2NybD9DQT02NDkyOEYwMjgyNzlFRjI1OTc1REE2OEM1RkU1OENBNkU5RTU0RUZGMB8GA1UdIwQYMBaAFMgyHkARfkHUu1UBr8xHGkI1RqvvMB0GA1UdDgQWBBSLF+8B2iz2iu4sqz+5HpQRAcJWCjANBgkqhkiG9w0BAQsFAAOCAQEAbrBinp4d6ZnJEqOi3bmKQQxqdlwUyQMSHB4GPS3fj/fai5tgfTmUudimwZZ/7IuG5y0iVIQidyxu7mkD4Euu8G/n8k/ll4ldXkCsbODQzxATsuu/MQLPleRUwjqJyJNKUMtXBysUGfXmchlJF2O1j9QW6MEAZJ+6ytbLlVnIEomdaubd0iw8NqVQzbYctcduLGst1kImZc/KhzT41sTSEW678odHSeYQIB+ghNy+NZXfwM49uSW3NwRsQAyll03wJCrXV2v3uIgUYgsLxdyyr9DuV/10Gq9Wq9pvT5RDZIL9b1gkR/1mGRlpbvoafG/fU/u9jdBZ6Tnh1VspDQXiZg== +-----END CERTIFICATE----- diff --git a/openssl/cmtp.p12 b/openssl/cmtp.p12 new file mode 100644 index 0000000000000000000000000000000000000000..084d78acea850d675c37848acd4136dbf1a98e4f GIT binary patch literal 4341 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 bSE2I@#)ha3jSMhu5|Unm^?i`zzgPSZv+pEd literal 0 HcmV?d00001 diff --git a/openssl/env.cmd b/openssl/env.cmd new file mode 100644 index 0000000..d6fea73 --- /dev/null +++ b/openssl/env.cmd @@ -0,0 +1 @@ +docker run -it --rm --workdir /app -v %cd%/:/app ubuntu bash diff --git a/openssl/sandbox.cer b/openssl/sandbox.cer new file mode 100644 index 0000000..bdd8db4 --- /dev/null +++ b/openssl/sandbox.cer @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0jCCAnagAwIBAgIFEFJXMIEwDAYIKoEcz1UBg3UFADBcMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRswGQYDVQQDDBJDRkNBIFRFU1QgU00yIE9DQTEwHhcNMjIxMTEwMDgzMDIx +WhcNMjQxMTEwMDgzMDIxWjB3MQswCQYDVQQGEwJjbjEVMBMGA1UECgwMQ0ZDQSBU +RVNUIENBMREwDwYDVQQLDAhDSVBTVEVTVDEOMAwGA1UECwwFVW5pdHMxLjAsBgNV +BAMMJTA0MUAzQ0lQU0NOU0hDTFJAQ04wMDAwMDAxMjlAMDAwMDAwMjIwWTATBgcq +hkjOPQIBBggqgRzPVQGCLQNCAAQBcmUrxvk1RPTcoVzLxFQR0LzkZVm2RTrjalzy +D4o2jDgVRtnbTE1VjIlONyCF5Zdg4vRg7o8tD2NCdxrEfRCKo4IBBjCCAQIwHwYD +VR0jBBgwFoAUa/4Y2o9COqa4bbMuiIM6NKLBMOEwDAYDVR0TAQH/BAIwADBIBgNV +HSAEQTA/MD0GCGCBHIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2Zj +YS5jb20uY24vdXMvdXMtMTQuaHRtMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly91 +Y3JsLmNmY2EuY29tLmNuL1NNMi9jcmw0MjAzNi5jcmwwDgYDVR0PAQH/BAQDAgM4 +MB0GA1UdDgQWBBTdpcORJFpsy4x4eYSFLQ3QvWv0BjAdBgNVHSUEFjAUBggrBgEF +BQcDAgYIKwYBBQUHAwQwDAYIKoEcz1UBg3UFAANIADBFAiEAgxPdf1pv7vPk9r2h +BZV7wHGXxVXz+LzpluIeWFyPw9QCIF40z5jvbwVnmdmrg2WEb44wtbIOM8Rsp9Ys +rMq5TTQt +-----END CERTIFICATE----- \ No newline at end of file diff --git a/openssl/sandbox.p12 b/openssl/sandbox.p12 new file mode 100644 index 0000000000000000000000000000000000000000..60e81cd393af1e6a645238f146c324727c1bd8b4 GIT binary patch literal 968 zcmV;(12_CIf&;_?0Ru3C1BwO-Duzgg_YDCD0ic2ddjx_5cQAqjb1;GfZw3h}hDe6@ z4FLxRpn?NnFoFYI0s#Opf&*0s2`Yw2hW8Bt2LUh~1_~;MNQUiqG|^$r5pBQ6Y>Q_;7X2bq&K_ zgXQN8GO6xG^me;lMy|0djfIrA!MHrb@0P<~mZ0H3-Ei_~ls0N^TEF4k!JzfG z?Q1sf2M8~z+>_Vli!8qJ@lWXF9f}b?m1dhL+R4?c7#KA z$YO}52oGanzeXKL;WS^4*s^W)3$V^F8XhX5-sq4U$T^wKECOj3K($GGO6P#ey`Fa! zm~L4e!VZ(>{?H%GB9Zh_O3SCRO(O&$4&CXay@nBTAW-Xqy-}vyxYI^f=cyGEyV*8- z#pn?bt^Q1WFd&M_Z>wQ9DQ8#Y9ASbBB!ma0HOgicrKc%5TaWG|*^^V=A9s?}l<5DC zp{*DV5g3Vis-&&HQTUMbAQA>YHjfo3j)ZU~*EwOuxhd?Rt?aT)_@PS0YCvU^4SO)a z4=mz5hIgDa`eFfhq8K0ulTNrPv9EO{M%8l?dWctiVa(R}KapN_8V0MnwPdugRkGIf zj^v`jDh85ui?#${Y7dpyvY6=VOwpv5^b5)PhrxyFCqX51m;Xo=cDe`_ezHa$V%jw~ z0DJXDLlj63W4>nvx)Y9wCAuImG+*6D^9l~*z=~*1sd$^>%*{+EAw)2!bB}3|QL+ZB z*$FZkl_5>EGu&Llvi)Or!1O_!COZik z=M;_3H9QIp{#w52^gX|;2_N?5ZKmxZK5;Rdsins!{%S6sH@f-{V%8M-0}JnndJQh? z@>pCx(wXg~DDu^KAmD29gFN;EE+cpjhRL(P`OvU+4MiRY8ME}jFflM8FbM_)D-Ht! q8U+9Z6zAn}R1~pNXPE6jU91`T9mbRr`UD6bok1A|HHRAl0tf&p8@8GN literal 0 HcmV?d00001 diff --git a/openssl/sandbox.pem b/openssl/sandbox.pem new file mode 100644 index 0000000..6c9349a --- /dev/null +++ b/openssl/sandbox.pem @@ -0,0 +1,23 @@ +Bag Attributes: +subject=C = cn, O = CFCA TEST CA, OU = CIPSTEST, OU = Units, CN = 041@3CIPSCNSHCLR@CN000000129@00000022 + +issuer=C = CN, O = China Financial Certification Authority, CN = CFCA TEST SM2 OCA1 + +-----BEGIN CERTIFICATE----- +MIIC0jCCAnagAwIBAgIFEFJXMIEwDAYIKoEcz1UBg3UFADBcMQswCQYDVQQGEwJD +TjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y +aXR5MRswGQYDVQQDDBJDRkNBIFRFU1QgU00yIE9DQTEwHhcNMjIxMTEwMDgzMDIx +WhcNMjQxMTEwMDgzMDIxWjB3MQswCQYDVQQGEwJjbjEVMBMGA1UECgwMQ0ZDQSBU +RVNUIENBMREwDwYDVQQLDAhDSVBTVEVTVDEOMAwGA1UECwwFVW5pdHMxLjAsBgNV +BAMMJTA0MUAzQ0lQU0NOU0hDTFJAQ04wMDAwMDAxMjlAMDAwMDAwMjIwWTATBgcq +hkjOPQIBBggqgRzPVQGCLQNCAAQBcmUrxvk1RPTcoVzLxFQR0LzkZVm2RTrjalzy +D4o2jDgVRtnbTE1VjIlONyCF5Zdg4vRg7o8tD2NCdxrEfRCKo4IBBjCCAQIwHwYD +VR0jBBgwFoAUa/4Y2o9COqa4bbMuiIM6NKLBMOEwDAYDVR0TAQH/BAIwADBIBgNV +HSAEQTA/MD0GCGCBHIbvKgEBMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2Zj +YS5jb20uY24vdXMvdXMtMTQuaHRtMDkGA1UdHwQyMDAwLqAsoCqGKGh0dHA6Ly91 +Y3JsLmNmY2EuY29tLmNuL1NNMi9jcmw0MjAzNi5jcmwwDgYDVR0PAQH/BAQDAgM4 +MB0GA1UdDgQWBBTdpcORJFpsy4x4eYSFLQ3QvWv0BjAdBgNVHSUEFjAUBggrBgEF +BQcDAgYIKwYBBQUHAwQwDAYIKoEcz1UBg3UFAANIADBFAiEAgxPdf1pv7vPk9r2h +BZV7wHGXxVXz+LzpluIeWFyPw9QCIF40z5jvbwVnmdmrg2WEb44wtbIOM8Rsp9Ys +rMq5TTQt +-----END CERTIFICATE----- diff --git a/openssl/user.p12 b/openssl/user.p12 new file mode 100644 index 0000000000000000000000000000000000000000..5ec1005458a357ac7471b83f5fa93707e89c2b0c GIT binary patch literal 976 zcmV;>126nAf&Jc=^{b_7?OSj%FSZn!?Jg|R1UcHO-f42W#&t>n23BK8r{v4egE#9 z46#jTZ(_f|N_2o3Gb#m0M=rCDjekgiInp{$DtfpXJXwe%rx2lUQX)xq(u7dLi;=kv zYZ)Ip#S}Mqzp3g=#%Mz<9Vaet(X+)kkE2(>Tw&x76U<(}@Bh*Ye;ntYuh2OUPH&w! zT!YBwn2*qPE&%7pnVXEQe-ZM9DTOdB8E zoCw_evv@Kn@dOFULqP*$M9*D@|R~ z>GPlx6b-JiN1^#Brj77`0nvu8y@{)MauO%j73Ga2hLL>#rUNp_YkVX8OR)xF?X>ov z8|lD;o=E?z5VpQE(vvV-aI?^ktVl_NW|IagiE~+p&tzjeIps9U&14TqC@tW!62VY^ zIbM1GFC5NZZ8(ni%2X&-v3@2K_vH7|{9Sx&Uqk0E@mze;3WRmzpIy(*+BfxV3oWoj ztk5Sc{cQbEPOa+g2qP3P9Resg?+?6a;~WwgLQQ%lo`x^8u4=>9U2ud;{+J)q!**jY zsuKMRGsEV#TiQZ$-*SiZ!MDQvufcS74jmac`KDxetOLNm<38p*{x5HDy}wY@dJlFk zahz`;TdY>b(UVCNrS3`S|_OueK%oXjO0UncpoYk|(;gJN% zedo@A%a(qU7mP@dlISn%h@ktw>4X3h!*J+En2-Az=C-1dcvDwSEu91XV2>G ze`o8>E09-FErvI!`x<|Lu|b`KDT#}XAVy~x&^JCjp2*1~j^IqA!I{%acJ}vRFflM8 yFbM_)D-Ht!8U+9Z6c#%Ri$yHj8n%5w>*W{_k215(cLWGm*>=I=PF52F0tf){Zovis literal 0 HcmV?d00001 diff --git a/private_key.pem b/private_key.pem new file mode 100644 index 0000000000000000000000000000000000000000..580f7f11a4dc23f31099d7650de7d3a209719194 GIT binary patch literal 150 zcmXqLoXo_?U?9xKuGQvo&X$RhjYF$Z=6on)lP*i8K{*p6Ba6c4DG;IM`&^?}X_%FW^FGTIj;;#K6K>Z*)fU^(OglTQkWp-j4=XjoyRXe$x3FR7@2}4{AUlQGgTcU+Ns(dR zflbS1UB6I!d&-$GyWZ|1|IB*JNz=<$aBJ|z-CWbWl}W)Npq_K45y!@=y{|X2tdcg- a%P|)=yLq?OnYXOMbN^;`1_ncj&lv#OqG=5P literal 0 HcmV?d00001 diff --git a/public_key.pem b/public_key.pem new file mode 100644 index 0000000000000000000000000000000000000000..d23ca4cb6db0ece6784f189953dc73484598028a GIT binary patch literal 91 zcmV-h0HpsgSuhg@2P%e0&OHJF1_&yF9M4q&f-M6=00aSlGR!IKqdmelc*MuH1+Ykd xCrp}zf1B0!doQdJmpZP~SO^&;i*;Do+(ecAZHlbnc_>$l)|sxMfVuni=diodC!_!X literal 0 HcmV?d00001 diff --git a/root.p12 b/root.p12 new file mode 100644 index 0000000000000000000000000000000000000000..d82888714284ed76ee66ca22e1decd7d7f9343ce GIT binary patch literal 3291 zcma)+c{tRK7RP627_#rXELne)eTnfh2q9u9J4Lb-#XE$NT}5Qenk+F{vhSI`5x4$pobO07m{%1r1k}#IV zFkhADtGuFjjGStNE**?9XnHn4AYu#7R^#il)17$TeZT~yux7Yt25(O^yB-Dlv@fIv#NH`Hfv~S8|;ruxp!F_fU7@*Hst7 z-ssz8uX%1OMFbh^u|D*{@McW5F#6~pLjQQ-->p@hnYQsRFco7g-tu1B{Yi`qzqemr&MAj+huO~Fo z%KVPTXOWkJ$;%$XK45KX)~|!3nS`NX-A=sxWEAvgt##T{ zUo*Y;gPpvr|BS6zEqiKo_ED5ldb6;=Y3XpXZy%6n5d^#+RVpone{58C)$mi)AnFiH zi?s}P&V;arMhZ?#%pdE()&mA%wQ7|^rC}>QeU;GAZ?hN^n!LAt@|S|VRK8R_0vjfwVxGV6CRH@Y=)J!O!GK(3&B=L$UUJGEY|KoPjC2;dQwf19Wfxp>5zbCeAMgU(CpKO6A>3T||$l^bZfxm9MOKC6kD z&=Ymq_wfG-?hq8Uk|lE}!8~TD*T28UHWZH#KxmnE7VsT0U7VEONvq<_sj1S7u<@wx zBym?=tC#(C?;gp(dDm#RY!!m)ntYfxkPUt;xMFC(?=*MZ{|l8e7k^SWA;bpb9GW^3 zC9SH>Tv;JqzzMJk1ri*eE3S@ekMe(}@!akRnt+a+cs6puK^m?ZwE>muGED!~>;? zArf<|^eC;FH>7I5-hMmTnGOe2e(-1If#!`@Z6Owvvr@6zNiFu7Fu$>zW%syxb9g0k zHp}Z)&J#9%M!HjPYNzCh;A1)k%vs}nv8oTGy*%G?YiIs}o-T!fHtF!@W#z`#T~FKN ze=D%bM2>^JF8NBfl|{>D6kn9tJ`?A&5oYubqo=YNLANx%eN#@>hweZFP94UOwJ(c2 z(Q`}qVs#SrFC2@aucF8G<>6H?o=*`{DgczomeNWF?G-km->_VPtj z{mgS;AE)BUGGvV7>SPd419m^~_eqq$`uNyoTP?wL%-Yw%uzPY*4Yw@lukl9r7o*Hv z;} zSYwp!k%413;V;PgWv=f({4ta$rrg4lMPgb3n;wSlE+@x~$0}pSbzcMkBd_x4prEgJ ze3zB|#A15b=C2tg%@NH+Qql=)O@AFez;#(QtkehC6p`b~p#^3>Ig?MLV<+aIY~ykx z2nj#|6fEmh9XgPZK58YL=KDHRxcqiV`#h|5Ns24sR-ndkQJv3PkdL#EP`89NkuRKd zI63z)LYbSsf+hiDThPv46G4!2u<@i18aPV(ksGsAwV{7w+pan1YEH(zAl9}A+%5}$ z%s#%onlYGUWKZVjgWcv$6M*S@#i;o)f!4qN_Q~-UeYYHxLU)rTh*Emita)WSKbP>h zC)wTG*(&zR&!UOc<^`0Iut2_8pybjC`(k#~u6$dy40uNabvMP*zD9|un{w#Z1!1Pv zs4L4~Eve%F(TU&<_N{zleah+B2JXF&2Glo zG6ke>^U*(X?4&D<6vsp{fw228H9$vkPHKxG6)kj(NpUmy{w;wH1_kexVLJnwk#f)< z-}{@>Q#uM+4FgCe=(8ph4;9MZ1^Chq#q1HgaA*abR9?#P^h&Ph-dLGLzQTt3-rMW6w!|8!JMSDN ztX@DXbSG<1yIVthqoZLugSp^{VtoD9aucIiFnQ@yWWIq9)?*`B$wJa zE>4!&VCjyYX=tsQvjpQenv|#5L5JH6Nz?X%Du?Q?mA(uLv;29eR?-%MQ{Bu<6OT=r zVCY~JF|Sgw!wD4xcnLYHob2VUi|}c4Rz-ZLp&$>OVUFjTyPMKg{mH) wGSj#Up3g#N`3=lpy%ok53}accn(0FnZs^FA2J*DLDs8nZ8PI`1!I8QD0?QlrM*si- literal 0 HcmV?d00001 diff --git a/sHSM.iml b/sHSM.iml new file mode 100644 index 0000000..58ada0c --- /dev/null +++ b/sHSM.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/chakracoin/shsm/logiclayer/SYDSignerBuilder.java b/src/main/java/com/chakracoin/shsm/logiclayer/SYDSignerBuilder.java new file mode 100644 index 0000000..e0a546e --- /dev/null +++ b/src/main/java/com/chakracoin/shsm/logiclayer/SYDSignerBuilder.java @@ -0,0 +1,29 @@ +package com.chakracoin.shsm.logiclayer; + +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.jcajce.io.OutputStreamFactory; +import org.bouncycastle.jcajce.util.DefaultJcaJceHelper; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.RuntimeOperatorException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; + +import java.io.OutputStream; +import java.security.GeneralSecurityException; +import java.security.PrivateKey; +import java.security.Signature; +import java.security.SignatureException; + +public class SYDSignerBuilder extends JcaContentSignerBuilder { + + public SYDSignerBuilder(String signatureAlgorithm) { + super(signatureAlgorithm); + } + + public ContentSigner build(PrivateKey privateKey) + throws OperatorCreationException + { + return null; + } + +} diff --git a/src/main/java/com/chakracoin/shsm/util/TripleDESUtil.java b/src/main/java/com/chakracoin/shsm/util/TripleDESUtil.java new file mode 100644 index 0000000..8e64b9a --- /dev/null +++ b/src/main/java/com/chakracoin/shsm/util/TripleDESUtil.java @@ -0,0 +1,83 @@ +package com.chakracoin.shsm.util; + +/** + * @Author:Cheney + * @Date:2023/7/20 16:11 + */ +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.DESedeKeySpec; +import javax.crypto.spec.IvParameterSpec; + +import static javax.swing.text.html.CSS.Attribute.PADDING; + +public class TripleDESUtil { + private static final String ALGORITHM = "DESede"; + private static final String PADDING = "PKCS5Padding"; + private static final String PADDING7 = "PKCS7Padding"; + private static final String NoPadd = "NoPadding"; + private static final String MODE = "CBC"; + + public static byte[] encrypt(byte[] data, byte[] keyBytes) throws Exception { + DESedeKeySpec spec = new DESedeKeySpec(keyBytes); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); + SecretKey key = keyFactory.generateSecret(spec); + + Cipher cipher = Cipher.getInstance(ALGORITHM); + cipher.init(Cipher.ENCRYPT_MODE, key); + + return cipher.doFinal(data); + } + + public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes) throws Exception { + DESedeKeySpec spec = new DESedeKeySpec(keyBytes); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); + SecretKey key = keyFactory.generateSecret(spec); + + Cipher cipher = Cipher.getInstance(ALGORITHM); + cipher.init(Cipher.DECRYPT_MODE, key); + + return cipher.doFinal(encryptedData); + } + + public static byte[] encryptCBC(byte[] data, byte[] keyBytes, byte[] iv) throws Exception { + DESedeKeySpec spec = new DESedeKeySpec(keyBytes); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); + SecretKey key = keyFactory.generateSecret(spec); + + Cipher cipher = Cipher.getInstance(ALGORITHM + "/" + MODE + "/" + PADDING); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); + + return cipher.doFinal(data); + } + + public static byte[] decryptCBC(byte[] encryptedData, byte[] keyBytes, byte[] iv) throws Exception { + DESedeKeySpec spec = new DESedeKeySpec(keyBytes); + SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); + SecretKey key = keyFactory.generateSecret(spec); + + Cipher cipher = Cipher.getInstance(ALGORITHM + "/" + MODE + "/" + NoPadd); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); + + return cipher.doFinal(encryptedData); + } + + + public static void main(String[] args) { + try { + String data = "Hello, world!"; + String key = "0123456789abcdef0123456789abcdef0123456789abcdef"; + byte[] encryptedData = encrypt(data.getBytes(), key.getBytes()); + byte[] decryptedData = decrypt(encryptedData, key.getBytes()); + + System.out.println("Original Data: " + data); + System.out.println("Encrypted Data: " + new String(encryptedData)); + System.out.println("Decrypted Data: " + new String(decryptedData)); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/test/java/Base64De.java b/src/test/java/Base64De.java new file mode 100644 index 0000000..27c59b3 --- /dev/null +++ b/src/test/java/Base64De.java @@ -0,0 +1,17 @@ +import com.chakracoin.shsm.util.Util; +import sun.misc.BASE64Decoder; +import sun.misc.BASE64Encoder; + +import java.io.*; + +public class Base64De { + public static void main(String[] args) throws IOException { + + String v = "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"; + + File f = new File("./112233.bin"); + OutputStream os = new FileOutputStream(f); + os.write( Util.decodeBase64( v ) ); + os.flush(); + } +} diff --git a/src/test/java/FileUtil.java b/src/test/java/FileUtil.java new file mode 100644 index 0000000..ea7af63 --- /dev/null +++ b/src/test/java/FileUtil.java @@ -0,0 +1,18 @@ +import java.io.File; +import java.util.Base64; + +/** + * @Author:Cheney + * @Date:2023/8/22 17:44 + */ +public class FileUtil { + public static void main(String[] args) { + + String crl = "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"; + byte[] ds = Base64.getDecoder().decode( crl ); + cn.hutool.core.io.FileUtil.writeBytes( ds , new File("./bin.crl")); + + + + } +} diff --git a/src/test/java/OpenCIPS.java b/src/test/java/OpenCIPS.java new file mode 100644 index 0000000..008b22b --- /dev/null +++ b/src/test/java/OpenCIPS.java @@ -0,0 +1,60 @@ +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.util.encoders.Hex; + +import java.io.FileInputStream; +import java.security.Key; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.Security; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Enumeration; + +public class OpenCIPS { + +// static { +// Security.addProvider(new BouncyCastleProvider()); +// } + + /** + * openssl cips 流程验证 + * use OpenSSL 1.1.1f 31 Mar 2020 + * @param args + */ + public static void main(String[] args) { + + try{ + Security.addProvider(new BouncyCastleProvider()); + CertificateFactory certFactory= CertificateFactory + .getInstance("X.509", "BC"); + + char[] keystorePassword = "123456".toCharArray(); + char[] keyPassword = "password".toCharArray(); + + + KeyStore keystore = KeyStore.getInstance("PKCS12", new BouncyCastleProvider()); + keystore.load(new FileInputStream("./openssl/sandbox.p12"), keystorePassword); +// KeyStore keystore = KeyStore.getInstance("PKCS12"); +// keystore.load(new FileInputStream("./mystore.p12"), "p12passphrase".toCharArray()); + Enumeration aliases = keystore.aliases(); + + + System.out.println( keystore.size() ); + String alias = ""; + while ( aliases.hasMoreElements() ) { + alias = aliases.nextElement(); + } + + System.out.println( alias ); + Certificate cert = keystore.getCertificate( alias ); + System.out.println(Hex.toHexString( cert.getPublicKey().getEncoded() )); + + + } catch (Exception ex){ + ex.printStackTrace(); + } + + } + +} diff --git a/src/test/java/RSA.java b/src/test/java/RSA.java new file mode 100644 index 0000000..de9bea1 --- /dev/null +++ b/src/test/java/RSA.java @@ -0,0 +1,253 @@ +import com.chakracoin.shsm.util.TripleDESUtil; +import com.chakracoin.shsm.util.Util; +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.asn1.x509.Extension; +import org.bouncycastle.asn1.x509.KeyUsage; +import org.bouncycastle.asn1.x509.X509Extensions; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.*; +import java.math.BigInteger; +import java.security.*; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Base64; +import java.util.Calendar; +import java.util.Date; + +/** + * @Author:Cheney + * @Date:2023/7/18 18:20 + */ +public class RSA { + public static void main(String[] args) throws Exception { + + // --- generate a key pair (you did this already it seems) + Ret root = getRootKeypair(); + Certificate cert1 = root.getCertificate(); + String certString1 = convertToString(cert1); + System.out.println(certString1); + + + Ret ret = getKeypair( root ); + // --- create the self signed cert + Certificate cert = ret.getCertificate(); + String certString = convertToString(cert); + System.out.println(certString); + + selfCheck( ret ); + + String kek = "651A6B4A8271DBA76E08516D6256B0C2F374EDF73CA42DC304DB1652EDCBDD1F6FFD20FB62F2C97660D9860D3E8C476774A9E2FE9F1D896F502D2CD204CCDD3561FECF9A71D5F2391889E35B46E3D98CC96D41F888CF10DC6C2AA4F0910DF152723A4C78281E48DE831641A004C38EC71D3ECBB126C47F804D4C3AD0406F4715E642463079B03B2BF3F5F2D558FC694A5624B8ABBC1C23308FFD43B84AB1C1E01999B24C6105FBAAC2289C9FA8EC99F3239A9E435C4533C751147357D68A6ABB08545C461D2A4D12AED80A49A2EB77053BFA452217D571F03A0266C1CD121A4739688C2286E82D57801A2FD9048DCE6AFEE5102AB98B73C95DC186DE4B8CF0B0"; + kek = "8024BADCC3C4D6B522FCA90F21BD58C530FAECA35BD003F5DDDB35309E18BB6A17AF00A234E835E794A00148FC8FE8DFBE80D53BE352478D4635F8E913F459A7F3AEA779D6BB08B5B2870250AB2B4E937FD54ECC4C9F0E48CC5D72ACFB4D2465FCA297D92D5AD06541C55F6502DBB89340245C03A15DAB08DC488B35E784747818197A5E90F329E84EB07C1DA11466C17DC0AB2F554123170A62470FCA6BE6EA20D49793217B6CD63C21B9B79153DADDD75DD7D9F44AC2C433965887F7DF2D83E22FC7F9A3F7EEFFF32A40420DDE1356F187741D832773309251569320A212708C1964427760990D769D5782ED54E18050E869785A5FD3AFFCE66356D4B04D1F"; + + + Cipher cipher2 = Cipher.getInstance("RSA"); + cipher2.init(Cipher.DECRYPT_MODE, ret.getPrivateKey()); + byte[] decryptedBytes = cipher2.doFinal(Util.hexString2Bytes(kek)); + System.out.println( "skey=" + Util.bytes2HexString( decryptedBytes ) ); +// +// byte[] eData = TripleDESUtil.encrypt(new byte[16], decryptedBytes); +// System.out.println("eData=" + Util.bytes2HexString(eData)); +// +// eData = TripleDESUtil.encryptCBC(new byte[16], decryptedBytes, new byte[8]); +// System.out.println("eData iv=" + Util.bytes2HexString(eData)); + + + byte[] oData = TripleDESUtil.decryptCBC( + Util.hexString2Bytes("C9F23109C2E315B2D400013540C40EF1"), + decryptedBytes, + Util.hexString2Bytes("0000000000000000") + ); +// 022C9E3062B41B87 022C9E3062B41B8741972DA126E19D5C +// 022C9E3062B41B87 D0D3FED3AD76DD9E 03999A52DF7D1AC4 +// 022C9E3062B41B87 D0D3FED3AD76DD9E 45058335009A98458DA9CF8CFF39209E + System.out.println("oData=" + Util.bytes2HexString(oData)); + System.out.println(new String(oData)); + + } + + private static void selfCheck(Ret ret) throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException { + + byte[] encryptedData = new byte[8]; + System.out.println("d1=" + Util.bytes2HexString(encryptedData)); + // 加密 + Cipher cipher1 = Cipher.getInstance("RSA"); + cipher1.init(Cipher.ENCRYPT_MODE, ret.getCertificate().getPublicKey()); + byte[] encryptedBytes = cipher1.doFinal(encryptedData); + + System.out.println("d2=" + Util.bytes2HexString(encryptedBytes)); + + // 解密 + Cipher cipher2 = Cipher.getInstance("RSA"); + cipher2.init(Cipher.DECRYPT_MODE, ret.getPrivateKey()); + byte[] decryptedBytes = cipher2.doFinal(encryptedBytes); + + System.out.println("d3=" + Util.bytes2HexString(decryptedBytes)); + System.out.println("--- 自检结束 ---"); + } + + private static Ret getRootKeypair() throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, OperatorCreationException, UnrecoverableKeyException { + + KeyStore testp12 = KeyStore.getInstance("PKCS12"); + File file = new File("root.p12"); + if ( file.exists() ) { + + try (FileInputStream p12 = new FileInputStream("root.p12")) { + testp12.load(p12, "p12passphrase".toCharArray()); + + PrivateKey key = (PrivateKey) testp12.getKey("privatekeyalias", "entrypassphrase".toCharArray()); + + return new Ret(key, testp12.getCertificate("cert")); + }catch (Exception e) { + e.printStackTrace(); + throw e; + } + + } else { + KeyPairGenerator rsaGen = KeyPairGenerator.getInstance("RSA"); + final KeyPair pair = rsaGen.generateKeyPair(); + + // --- create the self signed cert + Certificate cert = createSelfSigned(pair); + + // 存储 + KeyStore pkcs12 = KeyStore.getInstance("PKCS12"); + pkcs12.load(null, null); + + // --- create entry in PKCS12 + pkcs12.setKeyEntry("privatekeyalias", pair.getPrivate(), "entrypassphrase".toCharArray(), new Certificate[] {cert}); + + pkcs12.setCertificateEntry("cert", cert); + + // --- store PKCS#12 as file + try (FileOutputStream p12 = new FileOutputStream("root.p12")) { + pkcs12.store(p12, "p12passphrase".toCharArray()); + } + + + return new Ret(pair.getPrivate(), cert); + } + } + + private static Ret getKeypair(Ret root) throws NoSuchAlgorithmException, KeyStoreException, IOException, CertificateException, OperatorCreationException, UnrecoverableKeyException { + + KeyStore testp12 = KeyStore.getInstance("PKCS12"); + File file = new File("mystore.p12"); + if ( file.exists() ) { + + try (FileInputStream p12 = new FileInputStream("mystore.p12")) { + testp12.load(p12, "p12passphrase".toCharArray()); + + PrivateKey key = (PrivateKey) testp12.getKey("privatekeyalias", "entrypassphrase".toCharArray()); + + return new Ret(key, testp12.getCertificate("cert")); + }catch (Exception e) { + e.printStackTrace(); + throw e; + } + + } else { + KeyPairGenerator rsaGen = KeyPairGenerator.getInstance("RSA"); + final KeyPair pair = rsaGen.generateKeyPair(); + + // --- create the self signed cert + Certificate cert = createSigned(pair, root); + + // 存储 + KeyStore pkcs12 = KeyStore.getInstance("PKCS12"); + pkcs12.load(null, null); + + // --- create entry in PKCS12 + pkcs12.setKeyEntry("privatekeyalias", pair.getPrivate(), "entrypassphrase".toCharArray(), new Certificate[] {cert}); + + pkcs12.setCertificateEntry("cert", cert); + + // --- store PKCS#12 as file + try (FileOutputStream p12 = new FileOutputStream("mystore.p12")) { + pkcs12.store(p12, "p12passphrase".toCharArray()); + } + + + return new Ret(pair.getPrivate(), cert); + } + } + + private static X509Certificate createSigned(KeyPair pair, Ret root) throws OperatorCreationException, CertIOException, CertificateException { + X500Name dnName = new X500Name("CN=sunyard"); + X500Name issue = new X500Name("CN=root"); + BigInteger certSerialNumber = BigInteger.TEN; + + Date startDate = new Date(); // now + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(startDate); + calendar.add(Calendar.YEAR, 1); + Date endDate = calendar.getTime(); + + ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(root.getPrivateKey()); + + + JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(issue, certSerialNumber, startDate, endDate, dnName, pair.getPublic()); + KeyUsage keyUsage = new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.keyCertSign); + + certBuilder.addExtension(Extension.keyUsage, true, keyUsage); + + return new JcaX509CertificateConverter().getCertificate(certBuilder.build(contentSigner)); + } + + private static X509Certificate createSelfSigned(KeyPair pair) throws OperatorCreationException, CertIOException, CertificateException { + X500Name dnName = new X500Name("CN=root"); + BigInteger certSerialNumber = BigInteger.ONE; + + Date startDate = new Date(); // now + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(startDate); + calendar.add(Calendar.YEAR, 1); + Date endDate = calendar.getTime(); + + ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(pair.getPrivate()); + JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(dnName, certSerialNumber, startDate, endDate, dnName, pair.getPublic()); + + return new JcaX509CertificateConverter().getCertificate(certBuilder.build(contentSigner)); + } + public static String convertToString(Certificate certificate) { + try { + String cert_begin = "-----BEGIN CERTIFICATE-----\n"; + String end_cert = "\n-----END CERTIFICATE-----"; + + byte[] certBytes = certificate.getEncoded(); + return + cert_begin + + addNewline( Base64.getEncoder().encodeToString(certBytes) ) + + end_cert + ; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + public static String addNewline(String input) { + StringBuilder builder = new StringBuilder(input); + + int length = builder.length(); + for (int i = 64; i < length; i += 65) { + builder.insert(i, '\n'); + length++; + } + + return builder.toString(); + } +} diff --git a/src/test/java/RSAEncryptionExample.java b/src/test/java/RSAEncryptionExample.java new file mode 100644 index 0000000..95357cd --- /dev/null +++ b/src/test/java/RSAEncryptionExample.java @@ -0,0 +1,51 @@ +import javax.crypto.Cipher; +import java.nio.charset.StandardCharsets; +import java.security.*; +import java.util.Base64; + +public class RSAEncryptionExample { + public static KeyPair generateKeyPair() throws NoSuchAlgorithmException { + KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); + keyPairGenerator.initialize(2048); // 使用 2048 位的密钥长度 + return keyPairGenerator.generateKeyPair(); + } + + public static byte[] encryptWithPublicKey(String data, PublicKey publicKey) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.ENCRYPT_MODE, publicKey); + return cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); + } + + public static String decryptWithPrivateKey(byte[] encryptedData, PrivateKey privateKey) throws Exception { + Cipher cipher = Cipher.getInstance("RSA"); + cipher.init(Cipher.DECRYPT_MODE, privateKey); + byte[] decryptedBytes = cipher.doFinal(encryptedData); + return new String(decryptedBytes, StandardCharsets.UTF_8); + } + + public static void main(String[] args) { + try { + // 生成公钥和私钥 + KeyPair keyPair = generateKeyPair(); + PublicKey publicKey = keyPair.getPublic(); + PrivateKey privateKey = keyPair.getPrivate(); + + // 要加密的数据 + String data = "Hello, World!"; + + // 使用公钥加密数据 + byte[] encryptedData = encryptWithPublicKey(data, publicKey); + + // 将加密后的数据转换为 Base64 编码的字符串(方便在网络传输或存储) + String encryptedDataString = Base64.getEncoder().encodeToString(encryptedData); + System.out.println("Encrypted data: " + encryptedDataString); + + // 使用私钥解密数据 + byte[] decryptedBytes = Base64.getDecoder().decode(encryptedDataString); + String decryptedData = decryptWithPrivateKey(decryptedBytes, privateKey); + System.out.println("Decrypted data: " + decryptedData); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/test/java/Renzheng.java b/src/test/java/Renzheng.java new file mode 100644 index 0000000..ad27aa1 --- /dev/null +++ b/src/test/java/Renzheng.java @@ -0,0 +1,145 @@ +import com.chakracoin.shsm.logiclayer.SM4Util; +import com.chakracoin.shsm.util.Util; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.util.Random; + +public class Renzheng { + + private static final String path = "C:\\Users\\Cheney\\Desktop\\信达雅数据采集\\report1"; + private static final int len = 10; + + public static byte[] random(int len) { + byte[] data = new byte[len]; + new Random().nextBytes(data); + return data; + } + + public static String clean(String str) { + return str.replaceAll("\\s", ""); + } + + public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, IOException, IllegalBlockSizeException, NoSuchPaddingException, BadPaddingException, InvalidKeyException { + sm4de(); + } + + public static void sm4de() throws NoSuchAlgorithmException, NoSuchProviderException, IOException { + System.out.println("sm4 解密"); +// sm4de_ecb(); +// sm4de_cbc(); + + for ( int i = 0 ; i < 20 ; i ++ ) { + System.out.println( Util.bytes2HexString( random( 16 ) ) ); + } + + } + + + public static void writeLn(OutputStream fos, String str) throws IOException { + fos.write(str.getBytes()); + fos.write("\r\n".getBytes()); + fos.flush(); + } + + public static void sm4de_ecb() throws NoSuchAlgorithmException, NoSuchProviderException, IOException { + + File file = new File(path, "SM4_DEC_ECB.txt"); + if (file.exists()) { + file.delete(); + } + file.createNewFile(); + + try ( + FileOutputStream fos = new FileOutputStream(file) + + ) { + + + for (int i = 0; i < len; i++) { + byte[] key = SM4Util.generateKey(); + writeLn(fos, ""); + writeLn(fos, "密钥= " + Util.bytes2HexString(key)); + int len = (i + 1) * 16; + writeLn(fos, "密文长度= " + String.format("%08X", len)); + byte[] data1 = random(len); + writeLn(fos, "密文= " + Util.bytes2HexString(data1)); + byte[] data2 = SM4Util.decrypt_ECB_NoPadding(key, data1); + writeLn(fos, "明文= " + Util.bytes2HexString(data2)); + } + + } catch (IOException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } + + + } + + public static void sm4de_cbc() throws IOException { + + File file = new File(path, "SM4_DEC_CBC.txt"); + if (file.exists()) { + file.delete(); + } + file.createNewFile(); + + try ( + FileOutputStream fos = new FileOutputStream(file) + + ) { + + + for (int i = 0; i < len; i++) { + byte[] key = SM4Util.generateKey(); + byte[] iv = SM4Util.generateKey(); + writeLn(fos, ""); + writeLn(fos, "密钥= " + Util.bytes2HexString(key)); + writeLn(fos, "IV= " + Util.bytes2HexString(iv)); + + int len = (i + 1) * 16; + writeLn(fos, "密文长度= " + String.format("%08X", len)); + byte[] data1 = random(len); + writeLn(fos, "密文= " + Util.bytes2HexString(data1)); + byte[] data2 = SM4Util.decrypt_CBC_NoPadding(key, iv, data1); + writeLn(fos, "明文= " + Util.bytes2HexString(data2)); + } + + } catch (IOException e) { + e.printStackTrace(); + } catch (IllegalBlockSizeException e) { + e.printStackTrace(); + } catch (NoSuchPaddingException e) { + e.printStackTrace(); + } catch (BadPaddingException e) { + e.printStackTrace(); + } catch (InvalidKeyException e) { + e.printStackTrace(); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (NoSuchProviderException e) { + e.printStackTrace(); + } catch (InvalidAlgorithmParameterException e) { + e.printStackTrace(); + } + + + } + +} diff --git a/src/test/java/Ret.java b/src/test/java/Ret.java new file mode 100644 index 0000000..b14efee --- /dev/null +++ b/src/test/java/Ret.java @@ -0,0 +1,32 @@ +import java.security.cert.Certificate; +import java.security.PrivateKey; + +/** + * @Author:Cheney + * @Date:2023/7/18 18:34 + */ +public class Ret { + private PrivateKey privateKey; + private Certificate certificate; + + public Ret(PrivateKey privateKey, Certificate certificate) { + this.privateKey = privateKey; + this.certificate = certificate; + } + + public PrivateKey getPrivateKey() { + return privateKey; + } + + public void setPrivateKey(PrivateKey privateKey) { + this.privateKey = privateKey; + } + + public Certificate getCertificate() { + return certificate; + } + + public void setCertificate(Certificate certificate) { + this.certificate = certificate; + } +} diff --git a/src/test/java/SM2VerificationUtil.java b/src/test/java/SM2VerificationUtil.java new file mode 100644 index 0000000..ddb9b04 --- /dev/null +++ b/src/test/java/SM2VerificationUtil.java @@ -0,0 +1,26 @@ +//import com.chakracoin.shsm.logiclayer.SM2Util; +// +//public class SM2VerificationUtil { +// +// +// +// /** +// * SM2 外部公钥验签 +// * @param pk - 公钥 X Y 分量 +// * @param data - hash 后的数据 +// * @return 验签通过或不通过 +// */ +// boolean veritify(byte[] pk, byte[] data){ +// if ( null == pk +// || pk.length != 32 +// || null == data +// || data.length != 32 +// ) { +// throw new IllegalArgumentException(); +// } +// +// SM2Util.verify(); +// +// } +// +//} diff --git a/src/test/java/Test.java b/src/test/java/Test.java new file mode 100644 index 0000000..3f67d8e --- /dev/null +++ b/src/test/java/Test.java @@ -0,0 +1,39 @@ +import cn.hutool.core.io.FileUtil; +import com.chakracoin.shsm.logiclayer.BCECUtil; +import com.chakracoin.shsm.util.Util; +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import java.io.File; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.Security; +import java.security.spec.InvalidKeySpecException; + +/** + * @Author:Cheney + * @Date:2023/7/31 15:48 + */ +public class Test { + static { + Security.addProvider(new BouncyCastleProvider()); + } + + public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchProviderException { + + + + + String file = "C:\\Users\\Cheney\\weixin\\WeChat Files\\channe-wong\\FileStorage\\File\\2023-07\\KeyPair(1).txt"; +// String file = "D:\\chakracoin\\sHSM\\target\\ec.pkcs8.pri.der"; + + byte[] d = FileUtil.readBytes(new File(file)); + + System.out.println("hex=" + Util.bytes2HexString( d )); + byte []d2 = new byte[d.length -1]; + System.arraycopy( d, 0, d2, 0 , d2.length ); + System.out.println("hex=" + Util.bytes2HexString( d2 )); + BCECUtil.convertPKCS8ToECPrivateKey(d2); + System.out.println("over"); + + } +} diff --git a/src/test/java/com/chakracoin/shsm/cert/QPublicKey.java b/src/test/java/com/chakracoin/shsm/cert/QPublicKey.java new file mode 100644 index 0000000..78a96df --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/cert/QPublicKey.java @@ -0,0 +1,84 @@ +package com.chakracoin.shsm.cert; + + +import com.sunyard.ssp.BytesUtil; +import org.bouncycastle.asn1.ASN1OctetString; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; +import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo; +import org.bouncycastle.asn1.x9.X9ECPoint; +import org.bouncycastle.asn1.x9.X9ObjectIdentifiers; +import org.bouncycastle.crypto.params.ECDomainParameters; +import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil; +import org.bouncycastle.jce.ECNamedCurveTable; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec; +import org.bouncycastle.math.ec.ECCurve; +import org.bouncycastle.math.ec.ECPoint; + +import java.math.BigInteger; +import java.security.*; + +import static com.chakracoin.shsm.logiclayer.cert.SM2PublicKey.ID_SM2_PUBKEY_PARAM; + +public class QPublicKey implements PublicKey { + + private ECPoint q; + + public QPublicKey(ECPoint q) { + this.q = q; + } + + @Override + public String getAlgorithm() { + return "EC"; + } + + @Override + public String getFormat() { + return "PKCS#8"; + } + + @Override + public byte[] getEncoded() { + ASN1OctetString p = ASN1OctetString.getInstance( + new X9ECPoint(q, false).toASN1Primitive()); + + // stored curve is null if ImplicitlyCa + SubjectPublicKeyInfo info = new SubjectPublicKeyInfo( + new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ID_SM2_PUBKEY_PARAM), + p.getOctets()); + + byte[]s= KeyUtil.getEncodedSubjectPublicKeyInfo(info); + return s; + } + + + public static QPublicKey getQPublicKey(String der) throws NoSuchAlgorithmException, NoSuchProviderException { + + if (null == der || !der.startsWith("03420004") ) { + throw new IllegalArgumentException("公钥格式错误"); + } + + int headLen = 8; + int len = ( der.length() - 8 ) / 2; + + String strcertPKX = der.substring(headLen, headLen + 64); + String strcertPKY = der.substring(headLen + len, headLen + len + 64); + + BigInteger biX = new BigInteger(strcertPKX, 16); + BigInteger biY = new BigInteger(strcertPKY, 16); + + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); //载入bc库的支持 + + ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("sm2p256v1"); //获取bc库内置曲线参数,曲线名称sm2p256v1 + + ECDomainParameters ecDomainParameters = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN()); + + + ECCurve ecurve = ecDomainParameters.getCurve(); //获取曲线对象 + + ECPoint q = ecurve.createPoint(biX, biY); //创建公钥点 + + return new QPublicKey( q ); + } +} diff --git a/src/test/java/com/chakracoin/shsm/cert/SimplePublicKey.java b/src/test/java/com/chakracoin/shsm/cert/SimplePublicKey.java new file mode 100644 index 0000000..a00bc13 --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/cert/SimplePublicKey.java @@ -0,0 +1,47 @@ +package com.chakracoin.shsm.cert; + + +import com.sunyard.ssp.BytesUtil; + +import java.security.PublicKey; + +public class SimplePublicKey implements PublicKey { + + private byte[] encoded; + + public SimplePublicKey(String str) { + this.encoded = BytesUtil.hexString2Bytes( str ); + } + + @Override + public String getAlgorithm() { + return "EC"; + } + + @Override + public String getFormat() { + return "PKCS#8"; + } + + @Override + public byte[] getEncoded() { + return this.encoded; + } + + + public static SimplePublicKey getSimplePublickKey(String der) { + + if (null == der || !der.startsWith("03420004") ) { + throw new IllegalArgumentException("公钥格式错误"); + } + + int headLen = 8; + int len = ( der.length() - 8 ) / 2; + + String strcertPKX = der.substring(headLen, headLen + 64); + String strcertPKY = der.substring(headLen + len, headLen + len + 64); + der = "03420004" + strcertPKX + strcertPKY; + + return new SimplePublicKey("3059301306072A8648CE3D020106082A811CCF5501822D" + der ); + } +} diff --git a/src/test/java/com/chakracoin/shsm/shsm.iml b/src/test/java/com/chakracoin/shsm/shsm.iml new file mode 100644 index 0000000..3c376f3 --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/shsm.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/com/chakracoin/shsm/test/CmsApplication.java b/src/test/java/com/chakracoin/shsm/test/CmsApplication.java new file mode 100644 index 0000000..b2d9c2e --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/CmsApplication.java @@ -0,0 +1,197 @@ +//package mx.com.mostrotuille.example.cms; +// +//import java.io.ByteArrayInputStream; +//import java.io.ByteArrayOutputStream; +//import java.io.InputStream; +//import java.security.KeyFactory; +//import java.security.KeyStore; +//import java.security.PrivateKey; +//import java.security.Security; +//import java.security.cert.CertificateFactory; +//import java.security.cert.X509Certificate; +//import java.security.spec.PKCS8EncodedKeySpec; +//import java.util.ArrayList; +//import java.util.Base64; +//import java.util.Collection; +//import java.util.List; +// +//import org.bouncycastle.asn1.ASN1InputStream; +//import org.bouncycastle.asn1.cms.ContentInfo; +//import org.bouncycastle.cert.X509CertificateHolder; +//import org.bouncycastle.cert.jcajce.JcaCertStore; +//import org.bouncycastle.cms.CMSAlgorithm; +//import org.bouncycastle.cms.CMSEnvelopedData; +//import org.bouncycastle.cms.CMSEnvelopedDataGenerator; +//import org.bouncycastle.cms.CMSProcessableByteArray; +//import org.bouncycastle.cms.CMSSignedData; +//import org.bouncycastle.cms.CMSSignedDataGenerator; +//import org.bouncycastle.cms.KeyTransRecipientInformation; +//import org.bouncycastle.cms.RecipientInformation; +//import org.bouncycastle.cms.SignerInformation; +//import org.bouncycastle.cms.SignerInformationStore; +//import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; +//import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; +//import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; +//import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; +//import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; +//import org.bouncycastle.jce.provider.BouncyCastleProvider; +//import org.bouncycastle.operator.OutputEncryptor; +//import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +//import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; +//import org.bouncycastle.util.Store; +// +//public class CmsApplication { +// public static byte[] decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception { +// final CMSEnvelopedData envelopedData = new CMSEnvelopedData(encryptedData); +// +// final Collection recipients = envelopedData.getRecipientInfos().getRecipients(); +// +// final KeyTransRecipientInformation recipientInformation = (KeyTransRecipientInformation) recipients.iterator() +// .next(); +// +// return recipientInformation.getContent(new JceKeyTransEnvelopedRecipient(privateKey)); +// } +// +// public static byte[] encrypt(byte[] data, X509Certificate x509Certificate) throws Exception { +// final CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator(); +// cmsEnvelopedDataGenerator.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(x509Certificate)); +// +// final OutputEncryptor outputEncryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC) +// .setProvider(BouncyCastleProvider.PROVIDER_NAME).build(); +// +// final CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(new CMSProcessableByteArray(data), +// outputEncryptor); +// +// return cmsEnvelopedData.getEncoded(); +// } +// +// public static KeyStore getKeystore(InputStream keyStoreInputStream, String keyStorePassword) throws Exception { +// final KeyStore result = KeyStore.getInstance("jks"); +// result.load(keyStoreInputStream, keyStorePassword.toCharArray()); +// +// return result; +// } +// +// public static PrivateKey getPrivateKey(InputStream privateKeyInputStream, String password) throws Exception { +// final PKCS8Key pkcs8Key = new PKCS8Key(privateKeyInputStream, password.toCharArray()); +// +// final KeyFactory keyFactory = KeyFactory.getInstance("RSA"); +// +// final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(pkcs8Key.getDecryptedBytes()); +// +// return keyFactory.generatePrivate(pkcs8EncodedKeySpec); +// } +// +// public static PrivateKey getPrivateKey(KeyStore keyStore, String alias, String password) throws Exception { +// return (PrivateKey) keyStore.getKey(alias, password.toCharArray()); +// } +// +// public static X509Certificate getX509Certificate(InputStream certificateInputStream) throws Exception { +// return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certificateInputStream); +// } +// +// public static void main(final String[] ar) { +// try { +// Security.addProvider(new BouncyCastleProvider()); +// +// final ClassLoader classLoader = CmsApplication.class.getClassLoader(); +// +// final KeyStore keyStore = getKeystore(classLoader.getResourceAsStream("keystore.jks"), "mystorepassword"); +// +// final String message = "Hello, world!"; +// +// System.out.println("Data:\n" + message); +// +// byte[] signedData = sign(message.getBytes(), +// getX509Certificate(classLoader.getResourceAsStream("remitent.cer")), +// getPrivateKey(keyStore, "remitent_key", "remitentpassword")); +// +// byte[] encryptedData = encrypt(signedData, +// getX509Certificate(classLoader.getResourceAsStream("destinatary.cer"))); +// +// final String encryptedDataBase64 = Base64.getEncoder().encodeToString(encryptedData); +// +// System.out.println("\nEncrypted data (base 64):\n" + encryptedDataBase64); +// +// byte[] decryptedData = decrypt(Base64.getDecoder().decode(encryptedDataBase64), +// getPrivateKey(keyStore, "destinatary_key", "destinatarypassword")); +// +// if (verifySign(decryptedData)) { +// byte[] data = unsign(decryptedData); +// +// System.out.println("\nDecrypted data:\n" + new String(data)); +// } +// } catch (Exception ex) { +// ex.printStackTrace(); +// } +// } +// +// public static byte[] sign(byte[] data, X509Certificate x509Certificate, PrivateKey privateKey) throws Exception { +// final List x509CertificateList = new ArrayList(); +// x509CertificateList.add(x509Certificate); +// +// final CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator(); +// cmsGenerator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder( +// new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build()) +// .build(new JcaContentSignerBuilder("SHA256withRSA").build(privateKey), x509Certificate)); +// cmsGenerator.addCertificates(new JcaCertStore(x509CertificateList)); +// +// final CMSSignedData cmsSignedData = cmsGenerator.generate(new CMSProcessableByteArray(data), true); +// +// return cmsSignedData.getEncoded(); +// } +// +// public static byte[] unsign(byte[] decryptedData) throws Exception { +// final ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); +// +// final CMSSignedData cmsSignedData = new CMSSignedData(decryptedData); +// cmsSignedData.getSignedContent().write(outputStream); +// +// return outputStream.toByteArray(); +// } +// +// @SuppressWarnings("unchecked") +// public static boolean verifySign(byte[] signedData) throws Exception { +// ByteArrayInputStream inputStream = null; +// ASN1InputStream asn1InputStream = null; +// +// try { +// inputStream = new ByteArrayInputStream(signedData); +// asn1InputStream = new ASN1InputStream(inputStream); +// +// final CMSSignedData cmsSignedData = new CMSSignedData( +// ContentInfo.getInstance(asn1InputStream.readObject())); +// +// final Store certificates = cmsSignedData.getCertificates(); +// +// final SignerInformationStore signerInformationStore = cmsSignedData.getSignerInfos(); +// +// final Collection signers = signerInformationStore.getSigners(); +// +// final SignerInformation signer = signers.iterator().next(); +// +// final X509CertificateHolder x509CertificateHolder = ((Collection) certificates +// .getMatches(signer.getSID())).iterator().next(); +// +// return signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(x509CertificateHolder)); +// } catch (Exception ex) { +// throw ex; +// } finally { +// if (asn1InputStream != null) { +// try { +// asn1InputStream.close(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// if (inputStream != null) { +// try { +// inputStream.close(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// } +//} diff --git a/src/test/java/com/chakracoin/shsm/test/Keytools.java b/src/test/java/com/chakracoin/shsm/test/Keytools.java new file mode 100644 index 0000000..b40c381 --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/Keytools.java @@ -0,0 +1,58 @@ +package com.chakracoin.shsm.test; + +import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.openssl.PEMParser; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; +import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder; +import org.bouncycastle.operator.InputDecryptorProvider; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo; +import org.bouncycastle.pkcs.PKCSException; + +import java.security.cert.X509Certificate; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; +import java.security.PrivateKey; +import java.security.Security; +import java.security.cert.CertificateException; + +public class Keytools { + public static void main(String[] args) throws Exception { + readPem("D:\\fullstack\\gateway\\nginx\\test\\certs\\signkey.pem", "123456"); + } + + static PrivateKey readPem(String path, String password) + throws IOException, CertificateException, OperatorCreationException, PKCSException { + + Security.addProvider(new BouncyCastleProvider()); + PEMParser pemParser = new PEMParser(new FileReader(new File(path))); + PrivateKey privateKey = null; + X509Certificate cert = null; + Object object = pemParser.readObject(); + + while (object != null) { + JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); + if (object instanceof X509CertificateHolder) { + cert = new JcaX509CertificateConverter().getCertificate((X509CertificateHolder) object); + } + if (object instanceof PKCS8EncryptedPrivateKeyInfo) { + PKCS8EncryptedPrivateKeyInfo pinfo = (PKCS8EncryptedPrivateKeyInfo) object; + InputDecryptorProvider provider = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password.toCharArray()); + PrivateKeyInfo info = pinfo.decryptPrivateKeyInfo(provider); + privateKey = converter.getPrivateKey(info); + } + if (object instanceof PrivateKeyInfo) { + privateKey = converter.getPrivateKey((PrivateKeyInfo) object); + } + object = pemParser.readObject(); + } + + return privateKey; + } + +} diff --git a/src/test/java/com/chakracoin/shsm/test/PBKDF2Tool.java b/src/test/java/com/chakracoin/shsm/test/PBKDF2Tool.java new file mode 100644 index 0000000..d1edac2 --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/PBKDF2Tool.java @@ -0,0 +1,148 @@ +package com.chakracoin.shsm.test; + + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import java.math.BigInteger; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.KeySpec; + +/** + * PBKDF2加密工具 + * @author TF + */ + +public class PBKDF2Tool{ + + /** + * 算法 + */ + public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1"; + /** + * 盐的长度 + */ + public static final int SALT_BYTE_SIZE = 32 / 2; + /** + * 生成密文的长度 + */ + public static final int HASH_BIT_SIZE = 128 * 4; + /** + * 迭代次数 + */ + public static final int PBKDF2_ITERATIONS = 1000; + + /** + * @describe: 对输入的密码进行验证 + * @param: [attemptedPassword(待验证密码), encryptedPassword(密文), salt(盐值)] + * @return: boolean + */ + private static boolean authenticate(String attemptedPassword, String encryptedPassword, String salt) + throws NoSuchAlgorithmException, InvalidKeySpecException { + // 用相同的盐值对用户输入的密码进行加密 + String encryptedAttemptedPassword = getEncryptedPassword(attemptedPassword, salt); + // 把加密后的密文和原密文进行比较,相同则验证成功,否则失败 + return encryptedAttemptedPassword.equals(encryptedPassword); + } + + /** + * @describe: 生成密文 + * @param: [password(明文密码), salt(盐值)] + * @return: java.lang.String + */ + private static String getEncryptedPassword(String password, String salt) throws NoSuchAlgorithmException, + InvalidKeySpecException { + //参数 :明文密码 ,盐值,和迭代次数和长度生成密文 + KeySpec spec = new PBEKeySpec(password.toCharArray(), fromHex(salt), PBKDF2_ITERATIONS, HASH_BIT_SIZE); + //返回转换指定算法的秘密密钥的 SecretKeyFactory 对象 + //此方法从首选 Provider 开始遍历已注册安全提供者列表。返回一个封装 SecretKeyFactorySpi 实现的新 SecretKeyFactory 对象,该实现取自支持指定算法的第一个 Provider。 + SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM); + //根据提供的密钥规范(密钥材料)生成 SecretKey 对象。 然后以主要编码格式返回键,最后转换为16进制字符串 + return toHex(factory.generateSecret(spec).getEncoded()); + } + + + public static String gen(String message, String salt, int c, int dkLen) throws NoSuchAlgorithmException, InvalidKeySpecException { + //参数 :明文密码 ,盐值,和迭代次数和长度生成密文 + KeySpec spec = new PBEKeySpec(message.toCharArray(), fromHex(salt), c, dkLen * 8); + //返回转换指定算法的秘密密钥的 SecretKeyFactory 对象 + //此方法从首选 Provider 开始遍历已注册安全提供者列表。返回一个封装 SecretKeyFactorySpi 实现的新 SecretKeyFactory 对象,该实现取自支持指定算法的第一个 Provider。 + SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM); + //根据提供的密钥规范(密钥材料)生成 SecretKey 对象。 然后以主要编码格式返回键,最后转换为16进制字符串 + return toHex(factory.generateSecret(spec).getEncoded()); + } + + + /** + * @describe: 通过加密的强随机数生成盐(最后转换为16进制) + * @return: java.lang.String + */ + private static String generateSalt() throws NoSuchAlgorithmException { + //返回一个实现指定的 SecureRandom 对象 + //随机数生成器 (RNG) 算法。 + SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); + //生成盐 + byte[] salt = new byte[SALT_BYTE_SIZE]; + random.nextBytes(salt); + //返回16进制的字符串 + return toHex(salt); + } + + /** + * @describe: 十六进制字符串转二进制字符串 + * @param: [hex] + * @return: byte[] + */ + private static byte[] fromHex(String hex) { + byte[] binary = new byte[hex.length() / 2]; + for (int i = 0; i < binary.length; i++) { + binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16); + } + return binary; + } + + /** + * @describe: 二进制字符串转十六进制字符串 + * @param: [array] + * @return: java.lang.String + */ + private static String toHex(byte[] array) { + BigInteger bigInteger = new BigInteger(1, array); + String hex = bigInteger.toString(16); + int paddingLength = (array.length * 2) - hex.length(); + if (paddingLength > 0) { + return String.format("%0" + paddingLength + "d", 0) + hex; + } else { + return hex; + } + } + + /** + * 生成可以保存的数据 + * @param password 明文 + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + public static String generateStorngPasswordHash(String password) throws NoSuchAlgorithmException, InvalidKeySpecException { + //先获取盐值 + String salt = PBKDF2Tool.generateSalt(); + //生成密文 + String hash =PBKDF2Tool.getEncryptedPassword(password,salt); + return salt + ":" + hash; + } + + /** + * 明文密码和数据库保存的值比较 + * @param originalPassword 明文密码 + * @param storedPassword 数据库保存的值 + * @throws NoSuchAlgorithmException + * @throws InvalidKeySpecException + */ + public static boolean validatePassword(String originalPassword, String storedPassword) throws NoSuchAlgorithmException, InvalidKeySpecException { + String[] parts = storedPassword.split(":"); + String salt = parts[0]; + String hash = parts[1]; + return PBKDF2Tool.authenticate(originalPassword,hash,salt); + } +} diff --git a/src/test/java/com/chakracoin/shsm/test/PKCS7Test.java b/src/test/java/com/chakracoin/shsm/test/PKCS7Test.java new file mode 100644 index 0000000..1146f7a --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/PKCS7Test.java @@ -0,0 +1,162 @@ +package com.chakracoin.shsm.test; + +import cn.hutool.core.bean.BeanUtil; +import com.chakracoin.shsm.cert.TestX509; +import com.chakracoin.shsm.util.Util; +import com.sunyard.ssp.BytesUtil; +import lombok.SneakyThrows; +import org.bouncycastle.asn1.*; +import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.cms.CMSEnvelopedData; +import org.bouncycastle.cms.SydCmsUtil; +import org.springframework.context.annotation.Bean; + +import javax.security.auth.x500.X500Principal; +import java.io.*; +import java.nio.ByteBuffer; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +public class PKCS7Test { + + public static void write(String path, byte[] data){ + try { + File f = new File( path ); + if ( f.exists() ) { + f.createNewFile(); + } + FileOutputStream out = new FileOutputStream( f ); + try { + out.write( data ); + out.flush(); + out.close(); + } finally { + out.close(); + } + }catch ( Exception e ){ + e.printStackTrace(); + } + } + + + public static String read(String path){ + InputStream is = PKCS7Test.class.getResourceAsStream( path ); + try { + byte[] buff = new byte[ is.available() ]; + is.read( buff ); + return new String(buff); + } catch ( Exception e ){ + return null; + } + } + + + @SneakyThrows + private static final String dn8010(){ + byte[] dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1".getBytes("GBK"); + + byte[] data = new byte[256]; + Arrays.fill( data, (byte) 0 ); + System.arraycopy( dn, 0, data, 0, dn.length); + + ByteBuffer bb = ByteBuffer.allocate( 2 + data.length ); + bb.put( (byte)0x80 ); + bb.put( (byte)0x10 ); + bb.put( data ); + + return Util.bytes2HexString( bb.array() ); + } + + + private static void update(ContentInfo info, byte[] sessionKeyDer, byte[] enData , String sn, Mapissuer ) throws UnsupportedEncodingException { + // 修改 + ASN1Sequence seq = (ASN1Sequence) info.getContent().toASN1Primitive(); + + ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(1).toASN1Primitive()); + ASN1Sequence seq2 = (ASN1Sequence) set.getObjectAt( 0 ).toASN1Primitive(); + + // 会话密钥 + DEROctetString key = (DEROctetString) seq2.getObjectAt( 3 ); + BeanUtil.setFieldValue(key, "string", sessionKeyDer); + + // 签发信息段 + ASN1Sequence seq3 = (ASN1Sequence) seq2.getObjectAt( 1 ).toASN1Primitive(); + ASN1Integer isn = (ASN1Integer) seq3.getObjectAt(1 ).toASN1Primitive(); + BeanUtil.setFieldValue( isn, "bytes", Util.hexString2Bytes( sn ) ); + + + ASN1Sequence seq4 = (ASN1Sequence) seq3.getObjectAt( 0 ).toASN1Primitive(); + ASN1Set setO = (ASN1Set) seq4.getObjectAt(1).toASN1Primitive(); + ASN1Sequence seqO = (ASN1Sequence) setO.getObjectAt(0).toASN1Primitive(); + DERUTF8String o = (DERUTF8String) seqO.getObjectAt(1).toASN1Primitive(); + BeanUtil.setFieldValue(o, "string", issuer.get("O").getBytes("UTF-8") ); + + ASN1Set setCN = (ASN1Set) seq4.getObjectAt(2).toASN1Primitive(); + ASN1Sequence seqCn = (ASN1Sequence) setCN.getObjectAt(0).toASN1Primitive(); + DERUTF8String Cn = (DERUTF8String) seqCn.getObjectAt(1).toASN1Primitive(); + BeanUtil.setFieldValue(Cn, "string", issuer.get("CN").getBytes("UTF-8") ); + + // 密文段 + ASN1Sequence seq5 = (ASN1Sequence) seq.getObjectAt( 2 ).toASN1Primitive(); + ASN1TaggedObject tag = (ASN1TaggedObject) seq5.getObjectAt(2).toASN1Primitive(); + DEROctetString data = (DEROctetString) tag.getObject(); + BeanUtil.setFieldValue(data, "string", enData); + } + + + @SneakyThrows + public static void main(String[] args) { + + + System.out.println( new String( Util.encodeBase64( Util.hexString2Bytes( "308206F3060A2A811CCF550601040203A08206E3308206DF0201003181F83081F50201003065305C310B300906035504061302434E3130302E060355040A0C274368696E612046696E616E6369616C2043657274696669636174696F6E20417574686F72697479311B301906035504030C1243464341205445535420534D32204F43413102051049831419300D06092A811CCF5501822D030500047A307802205116E5F25813AF0D2040644B957B7CAE9E68E9E87BB3AE5D3CB39E239CD0C36502202FD68A8502A2D7003F61BBA2E8D77961C2B2384073DA20BE29B93F6716D1ADDF042042710FF6D9B44877F36BF7964351364F38293D15DE071D02B58DED7E55064135041071F2751A6C5B5706001C7FDFEA619645308205DD060A2A811CCF550601040201301B06072A811CCF55016804103ABB33F57AA5E2D454367BE8B31DC7C7808205B0ADEC723D48E3E1D11E7DDC540742283C98A24A101E19C2CD7DAE99ED499D7C8BBEEB6E3BF28AD63E00E821393F5250BA1C875355AD91A6ADF8A8B899EEB2AEB719EDE451B6881550DB5B8032C97DA4C07F474998E8663447CAD702AEC10C01A3B11B5D23A9FB02307B4C9B232C5B23509E58E3D0AAD3C84E953C2707D46F7359DCC6222C69D0A2257D5254F1E5CD1D685A9F48C38BB92709AACC23F5ABDBC9BC1D720A578C145A52AFD760E9176F8731037BD0AF7D8DFE303283FE9F497EDFCA15AE57B1A739A903C644BA79C065705DA7EE04BF0AB4CAE6FEBC7747508A95D7C320EB092EA321F1E4DACCDB5F0FB13AF88E7E53E352E86284880027255C8DE166808B7BF86CCC453B7CE48BBBBC8F5CEF36F06C7BCB1517DD91FFAAC0DD1CF45DF12584323EEE78A3536B2C2F939B77859200E8E6C8F628D62C1FDA87632821047999756E6DF5D65C5A8D8A37FF8EAE891B9307F27F488B3B3F0604AB2455550D3A6EE9B288260FD2EE481B4553DB6211A22EA66ED34406F30788DCD6C917426E771A113D49154D891841F14424786E7AE00FE88B8D98D74DC284EB9A645D27F9C37E7DE12E4F3EFA0D2686F1E42AF26153F705FC80D5EB9FF3AA6BCA920C6A9E3D84485E1335CF4A261E052368A0BB9C64E50EEC8D24DF2BDE58AF43ED1C0C3BEA4B1DB32D0E5ECD1D2FFD641557B558E67871F27343217991B0CC4A5AC568A9FEE0500060B4BECD085DD54A2E87B2F5BB3C3132F725ACB72577BA3C920095431652D662889189E843A90857ACDBDBF2F1B638CCA59E65AD06A7CB1644F82E412E7CD9892F17E10E0888B255FD9905EB4F6FA1E4C6056910262F57CF41839CB5F27099080AB7A514499D7A141C1B1E816EA40AD61837416823BF5CE3FA93D8777DC9F9488F8877873CF2D26C54E4C3082569DD4DF7101AE3A9DAEBE891B10F803F867EE3470B9209B677219AF8B6CB5833EEF9F8C9532D57A7DC82AD6AA7590D9F4158C526544C7BFDAAFB8C3F1684ABEEF825A95D1E70744A8F72C00F0B3D27E6217469F66C9786B1C04DAE6E0AD3BD980CF1D51316D583DFBDCA15529BD5CB7C69AD48B4731D6E8787D8A27A5F194E439B6D253E9E4FF76D89C26614D93441EC0B4195E0B44AD02C297598C98BE474EA102198C10202E707B11D500F747C8A0F6D51F4035CD2AF54F4CB6FDF2BDC827FAD8649E903436634DDF002389B99CDD8968C2CBD91B0BB4BA648A1698912B0C29250CD060E08A55C854EA25F948424DD028527ABF880DDF29AB8DE742303B7818BC3F145747FF496BDB79FC7625E341E96B434531FC4E0171E32875E6DA92CBAA8816BA05A8D96D15314A0AE61A440F67F880E87896E3FF45E27551A8ED2F8C19E33B690F8CD600F4366488B386261B6D5D2534378056891C8F0218D26EE1160A027AB18D9BA0189CB3EA682EDEF04FAA68E85EF585BE0250FCEE8E55845F2AA737D7BFF36ECE44410E4CDE4B283740008D7E2B93E4211D0F59B56351937B2EF653401762C8A89CAD446EF0B0D6828F69FF3F57FDDBFF7B6422D838959DB5C4988201549394ABFCDEB44E3BB76A7E359CD3DE81E52D0F24DFEEFEDE99397227B48C192DDF6F3883E6360FACDB3A93FE8048F917CC0B7272682A836ED1BCA87DB7114E8ACCDA617C366B7ED3C77F6367B86C7CA84F26354C8CACB09A2584878A5FA6BC6CA2C8E6BD6E05C3F2DEAAF7452CC7AC97F96CDF8A147FF743FFF0CA3EB21D84BC57957EAB721FCEAA739DE8588463188BFFE75AEE8A0536AF32755F6EF06CCF12B28BC83B696A4D4713C4416CB0AC478276EC221BAEC53C05B6CDB9BAD541923C8F308EABED085C925583CBBFC527EB45B0E9F29073183F19F2B85B962F1CB38DBA4DFAD5C8AC49D07ED82338AF61508285BC5DB90C325AD6A3040651D0B8FC6563833DDD28992B495A27DDB0BE250A69155E830328E16E072D98BC82BF30410E8E70B43E8DE50DA3DB06F4F1998543368B67143D317525A9CD89990CFAECFC042DFD3A93510B5A8E7BADA30732C34A23ED94E70266CDC9986D425" ) ) ) ); + + + +// String base64 = "4D4949473877594B4B6F45637A315547415151434136434342754D7767676266416745414D5948344D494831416745414D4755775844454C4D416B474131554542684D43513034784D44417542674E5642416F4D4A304E6F6157356849455A70626D467559326C68624342445A584A3061575A7059324630615739754945463164476876636D6C30655445624D426B47413155454177775351305A445153425552564E5549464E4E4D694250513045784167555153594D554754414E42676B7167527A50565147434C514D46414152364D4867434946455735664A594536384E4945426B53355637664B3665614F6E6F65374F755854797A6E694F63304D4E6C41694176316F714641714C584144396875364C6F31336C687772493451485061494C34707554396E4674477433775167516E455039746D305348667A612F655751314532547A6770505258654278304374593374666C5547515455454548487964527073573163474142782F332B70686C6B55776767586442676F7167527A5056515942424149424D42734742797142484D395641576745454471374D2F563670654C5556445A37364C4D6478386541676757777265787950556A6A34644565666478554230496F504A69695368416547634C4E6661365A37556D646649752B36323437386F72575067446F49546B2F556C4336484964545661325270713334714C695A37724B7574786E743546473269425651323175414D736C39704D422F52306D593647593052387258417137424441476A7352746449366E37416A4237544A736A4C46736A554A3559343943713038684F6C54776E4239527663316E6378694973616443694A5831535650486C7A52316F57703949773475354A776D717A4350317139764A76423179436C654D464670537239646736526476687A4544653943766659332B4D444B442F70394A66742F4B466135587361633571515047524C70357747567758616675424C384B744D726D2F7278335231434B6C646644494F734A4C714D68386554617A4E7466443745362B49352B552B4E5336474B456941416E4A56794E3457614169337634624D78464F337A6B693775386A317A764E76427365387356463932522F36724133527A305866456C6844492B376E696A553273734C354F6264345753414F6A6D7950596F31697766326F646A4B434545655A6C31626D3331316C78616A596F332F34367569527554422F4A2F5349733750775945717952565651303662756D79694359503075354947305654323249526F69366D62744E4542764D48694E7A5779526443626E63614554314A4655324A4745487852435234626E7267442B694C6A5A6A5854634B453635706B58536635773335393453355050766F4E4A6F627835437279595650334266794131657566"; +// System.out.println( Util.bytes2HexString( Util.decodeBase64( new String( Util.hexString2Bytes( base64 ) ) ) ) ); + + + write("./cms.p7", new byte[2]); + + String dm1 = read("/dm/dm1.p7"); + System.out.println("dm1.base64=" + dm1); + byte[] dm = Util.decodeBase64( dm1 ); + System.out.println("dm1.hex=" + Util.bytes2HexString( dm ) ); + +// CMSEnvelopedData cms = SydCmsUtil.getCMSEnvelopedData( dm ); +// System.out.println( cms ); + + + ContentInfo info = SydCmsUtil.getContentInfo( dm ); + System.out.println( info ); + + byte[] test = new byte[ 20 * 1024 * 1024 ]; + Arrays.fill( test, (byte) 0x0F ); + Mapmap = new HashMap<>(); + map.put("C", "CN"); + map.put("O", "组织"); + map.put("CN", "不知道"); + +// update( info , test, test, map); + + byte[] dm2 = info.getEncoded(); + System.out.println( Util.bytes2HexString( dm2 ) ); + ContentInfo info2 = SydCmsUtil.getContentInfo( dm ); + System.out.println( info2 ); + +// System.out.println( dn8010() ); +// +// +// System.out.println( +// +// new String( Util.hexString2Bytes( "433D434E2C4F3D43464341204F4341312C4F553D594343412C4F553D496E646976696475616C2D322C434E3D5943434140BBC6BDF0BDBBD2D7CBF9405A6875616E676A4031" ) , "GBK") +// ); + +// PKCS7Util.openEnvelope( ); + + + + } +} diff --git a/src/test/java/com/chakracoin/shsm/test/PKCS7Util.java b/src/test/java/com/chakracoin/shsm/test/PKCS7Util.java new file mode 100644 index 0000000..2326ac6 --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/PKCS7Util.java @@ -0,0 +1,233 @@ +package com.chakracoin.shsm.test; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.security.KeyStore; +import java.security.PrivateKey; +import java.security.Provider; +import java.security.Security; +import java.security.cert.Certificate; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaCertStore; +import org.bouncycastle.cms.*; +import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; +import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; +import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; +import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; +import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; +import org.bouncycastle.util.Store; +import org.bouncycastle.util.encoders.Base64; + +import static org.bouncycastle.asn1.ASN1Encoding.DL; + +public class PKCS7Util extends GMBaseTest { + public PKCS7Util() { + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + } + + + private static String ksType = "PKCS12"; + + /** + * 生成数字签名 + * @param srcMsg 源信息 + * @param charSet 字符编码 + * @param certPath 证书路径 + * @param certPwd 证书密码 + * @return + */ + public static byte[] signMessage(String srcMsg, String charSet, String certPath, String certPwd) { + String priKeyName = null; + char passphrase[] = certPwd.toCharArray(); + + try { + Provider provider = new BouncyCastleProvider(); + // 添加BouncyCastle作为安全提供 + Security.addProvider(provider); + + // 加载证书 + KeyStore ks = KeyStore.getInstance(ksType); + ks.load(new FileInputStream(certPath), passphrase); + + if (ks.aliases().hasMoreElements()) { + priKeyName = ks.aliases().nextElement(); + } + + Certificate cert = (Certificate) ks.getCertificate(priKeyName); + + // 获取私钥 + PrivateKey prikey = (PrivateKey) ks.getKey(priKeyName, passphrase); + + X509Certificate cerx509 = (X509Certificate) cert; + + List certList = new ArrayList(); + certList.add(cerx509); + + CMSTypedData msg = (CMSTypedData) new CMSProcessableByteArray( + srcMsg.getBytes(charSet)); + + Store certs = new JcaCertStore(certList); + + CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); + ContentSigner sha1Signer = new JcaContentSignerBuilder( + "SHA1withRSA").setProvider("BC").build(prikey); + + gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder( + new JcaDigestCalculatorProviderBuilder().setProvider("BC") + .build()).build(sha1Signer, cerx509)); + + gen.addCertificates(certs); + + CMSSignedData sigData = gen.generate(msg, true); + + return Base64.encode(sigData.getEncoded()); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 验证数字签名 + * @param signedData + * @return + */ + public static boolean signedDataVerify(byte[] signedData) { + boolean verifyRet = true; + try { + // 新建PKCS#7签名数据处理对象 + CMSSignedData sign = new CMSSignedData(signedData); + + // 添加BouncyCastle作为安全提供 + Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); + + // 获得证书信息 + Store certs = sign.getCertificates(); + + // 获得签名者信息 + SignerInformationStore signers = sign.getSignerInfos(); + Collection c = signers.getSigners(); + Iterator it = c.iterator(); + + // 当有多个签名者信息时需要全部验证 + while (it.hasNext()) { + SignerInformation signer = (SignerInformation) it.next(); + + // 证书链 + Collection certCollection = certs.getMatches(signer.getSID()); + Iterator certIt = certCollection.iterator(); + X509CertificateHolder cert = (X509CertificateHolder) certIt + .next(); + + // 验证数字签名 + if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder() + .setProvider("BC").build(cert))) { + verifyRet = true; + } else { + verifyRet = false; + } + } + + } catch (Exception e) { + verifyRet = false; + e.printStackTrace(); + System.out.println("验证数字签名失败"); + } + return verifyRet; + } + + /** + * 加密数据 + * @param srcMsg 源信息 + * @param certPath 证书路径 + * @param charSet 字符编码 + * @return + * @throws Exception + */ + public static String envelopeMessage(String srcMsg, String certPath, String charSet) throws Exception { + CertificateFactory certificatefactory; + X509Certificate cert; + // 使用公钥对对称密钥进行加密 //若此处不加参数 "BC" 会报异常:CertificateException - + certificatefactory = CertificateFactory.getInstance("X.509", "BC"); + // 读取.crt文件;你可以读取绝对路径文件下的crt,返回一个InputStream(或其子类)即可。 + InputStream bais = new FileInputStream(certPath); + + cert = (X509Certificate) certificatefactory.generateCertificate(bais); + + //添加数字信封 + CMSTypedData msg = new CMSProcessableByteArray(srcMsg.getBytes(charSet)); + + CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator(); + + edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator( + cert).setProvider("BC")); + + CMSEnvelopedData ed = edGen.generate(msg, + new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC) + .setProvider("BC").build()); + + ContentInfo info = ed.toASN1Structure(); + + String rslt = new String(Base64.encode(info.getEncoded( DL ))); + + System.out.println(rslt); + return rslt; + } + + /** + * 解密数据 + * @param encode 加密后的密文 + * @param certPath 证书路径 + * @param certPwd 证书密码 + * @param charSet 字符编码 + * @return + * @throws Exception + */ + public static String openEnvelope(String encode, String certPath, String certPwd, String charSet) throws Exception { + //获取密文 + CMSEnvelopedData ed = new CMSEnvelopedData(Base64.decode(encode.getBytes())); + + RecipientInformationStore recipients = ed.getRecipientInfos(); + + Collection c = recipients.getRecipients(); + Iterator it = c.iterator(); + + // 加载证书 + KeyStore ks = KeyStore.getInstance(ksType); + ks.load(new FileInputStream(certPath), certPwd.toCharArray()); + + String priKeyName = null; + if (ks.aliases().hasMoreElements()) { + priKeyName = ks.aliases().nextElement(); + } + + // 获取私钥 + PrivateKey prikey = (PrivateKey) ks.getKey(priKeyName, certPwd.toCharArray()); + + byte[] recData = null; + + //解密 + if (it.hasNext()) { + RecipientInformation recipient = (RecipientInformation) it.next(); + + recData = recipient.getContent(new JceKeyTransEnvelopedRecipient( + prikey).setProvider("BC")); + } + + return new String(recData, charSet); + } +} diff --git a/src/test/java/com/chakracoin/shsm/test/PKKDF2Test.java b/src/test/java/com/chakracoin/shsm/test/PKKDF2Test.java new file mode 100644 index 0000000..6254e56 --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/PKKDF2Test.java @@ -0,0 +1,17 @@ +package com.chakracoin.shsm.test; + +import java.security.NoSuchAlgorithmException; +import java.security.spec.InvalidKeySpecException; + +// Bouncycastle pkcs5PBKDF2 +public class PKKDF2Test { + public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException { + + String key = PBKDF2Tool.gen("11111111", "B88480FD1ED2DC09", 2048, 8 ); + System.out.println( key ); + + + // "89 66 71 6C AD 2B F8 11 A6 43 3E ED F0 83 39 41 52 EB 42 87 8B 17 32 83 0E B2 F5 E9 BD 8E 5B AB 91 B8 81 05 54 C9 F4 87 5E C7 BE E7 5B 17 3D 95 F2 E0 55 D2 D8 62 3C 83 19 C6 E4 A3 DE D9 3A 6E 00 8B 43 19 C1 CE 22 69 EF D2 43 F5 8F 2C 11 0C 9B 53 61 F6 A6 05 B1 CF CF 40 64 01 48 41 FE 20 2D 3B CA 02 4F 9C 07 C5 E6 89 24 F8 BF 7F 9E 03 AD FC AA 91 6D FF E5 55 83 B1 8D 8C 99 AE 81 ED 0F F9 8B 27 27 93 B0 81 87 74 A3 31 6D 45 DB FE "; + + } +} diff --git a/src/test/java/com/chakracoin/shsm/test/SM2KeyUtilTest.java b/src/test/java/com/chakracoin/shsm/test/SM2KeyUtilTest.java new file mode 100644 index 0000000..726ecec --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/SM2KeyUtilTest.java @@ -0,0 +1,67 @@ +package com.chakracoin.shsm.test; + +import com.chakracoin.shsm.logiclayer.SM2Util; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.openssl.PEMWriter; +import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter; + +import java.io.*; +import java.security.KeyPair; +import java.security.Security; + +public class SM2KeyUtilTest { + public static void main(String[] args) throws Exception { + + AsymmetricCipherKeyPair keyPair = SM2Util.generateKeyPairParameter(); + ECPrivateKeyParameters priKey = (ECPrivateKeyParameters) keyPair.getPrivate(); + ECPublicKeyParameters pubKey = (ECPublicKeyParameters) keyPair.getPublic(); + + String der = privateKeyToDER(priKey); + + System.out.println( der ); + + // SO22963581BCPEMPrivateEC(); + } + + /** + * 仅支持国密标准 SM2 密钥 + * 便利法门,并不严谨 + * @param priKey + */ + static String privateKeyToDER(ECPrivateKeyParameters priKey ){ + String hex = priKey.getD().toString(16); + return privateKeyToDer( hex ); + } + + + /** + * 仅支持国密标准 SM2 密钥 + * 便利法门,并不严谨 + * @param hexKey 长度 64 + * @return + */ + static String privateKeyToDer(String hexKey){ + + + final String head = "-----BEGIN EC PARAMETERS-----\n" + + "BggqgRzPVQGCLQ==\n" + + "-----END EC PARAMETERS-----\n" + + "-----BEGIN EC PRIVATE KEY-----\n"; + + final String tail = "\n-----END EC PRIVATE KEY-----"; + + return head + "30310201010420" + hexKey + "a00a06082a811ccf5501822d" + tail; + } + + +// static void SO22963581BCPEMPrivateEC() throws Exception { +// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); +// Reader rdr = new StringReader( ); +// Object parsed = new org.bouncycastle.openssl.PEMParser(rdr).readObject(); +// KeyPair pair = new org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter().getKeyPair((org.bouncycastle.openssl.PEMKeyPair) parsed); +// System.out.println(pair.getPrivate().getAlgorithm()); +// } + +} diff --git a/src/test/java/com/chakracoin/shsm/test/t.java b/src/test/java/com/chakracoin/shsm/test/t.java new file mode 100644 index 0000000..ae1398d --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/t.java @@ -0,0 +1,79 @@ +//package com.chakracoin.shsm.test; +// +//import org.bouncycastle.cms.*; +//import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; +//import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; +//import org.bouncycastle.jce.provider.BouncyCastleProvider; +//import org.bouncycastle.operator.OutputEncryptor; +//import org.bouncycastle.util.io.pem.PemObject; +//import org.bouncycastle.util.io.pem.PemReader; +// +//import javax.crypto.*; +//import java.io.*; +//import java.security.*; +//import java.security.cert.CertificateEncodingException; +//import java.security.cert.CertificateException; +//import java.security.cert.CertificateFactory; +//import java.security.cert.X509Certificate; +// +//public class PKCS7EnvelopExample { +// public static void main(String[] args) { +// Security.addProvider(new BouncyCastleProvider()); +// +// try { +// // 读取RSA公钥证书 +// X509Certificate recipientCert = readCertificate("public_key.pem"); +// +// // 生成对称密钥 +// KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); +// keyGenerator.init(256); // 使用256位密钥 +// SecretKey symmetricKey = keyGenerator.generateKey(); +// +// // 加密明文 +// byte[] plaintext = "Hello, World!".getBytes(); +// byte[] ciphertext = encryptWithAES(plaintext, symmetricKey); +// +// // 创建PKCS7数字信封 +// byte[] envelope = createPKCS7Envelope(ciphertext, symmetricKey, recipientCert); +// +// // 保存PKCS7数字信封到文件 +// FileOutputStream fileOutputStream = new FileOutputStream("envelope.p7"); +// fileOutputStream.write(envelope); +// fileOutputStream.close(); +// +// System.out.println("PKCS7 envelope created successfully."); +// +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// private static X509Certificate readCertificate(String filePath) throws IOException, CertificateException { +// FileInputStream fileInputStream = new FileInputStream(filePath); +// CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); +// X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(fileInputStream); +// fileInputStream.close(); +// return certificate; +// } +// +// private static byte[] encryptWithAES(byte[] plaintext, SecretKey symmetricKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, IllegalBlockSizeException { +// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); +// cipher.init(Cipher.ENCRYPT_MODE, symmetricKey); +// return cipher.doFinal(plaintext); +// } +// +// private static byte[] createPKCS7Envelope(byte[] ciphertext, SecretKey symmetricKey, X509Certificate recipientCert) throws CertificateEncodingException, CMSException, IOException, OperatorCreationException, CertificateEncodingException { +// CMSEnvelopedDataGenerator envelopedDataGenerator = new CMSEnvelopedDataGenerator(); +// +// JceKeyTransRecipientInfoGenerator recipientInfoGenerator = new JceKeyTransRecipientInfoGenerator(recipientCert); +// envelopedDataGenerator.addRecipientInfoGenerator(recipientInfoGenerator); +// +// CMSTypedData cmsTypedData = new CMSProcessableByteArray(ciphertext); +// +// OutputEncryptor outputEncryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC).setProvider("BC").build(); +// +// CMSEnvelopedData cmsEnvelopedData = envelopedDataGenerator.generate(cmsTypedData, outputEncryptor); +// +// return cmsEnvelopedData.getEncoded(); +// } +//} \ No newline at end of file diff --git a/src/test/java/com/chakracoin/shsm/test/t2.java b/src/test/java/com/chakracoin/shsm/test/t2.java new file mode 100644 index 0000000..6dc09c6 --- /dev/null +++ b/src/test/java/com/chakracoin/shsm/test/t2.java @@ -0,0 +1,17 @@ +package com.chakracoin.shsm.test; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import java.io.InputStream; +import java.security.Security; + +public class t2 { + + static { + Security.addProvider(new BouncyCastleProvider()); + } + public static void main(String[] args) throws Exception { + PKCS7Util.envelopeMessage("1111", "D:\\docker\\nginx\\conf\\domain.crt", "utf-8"); + + } +} diff --git a/src/test/java/example/SM2Kit.java b/src/test/java/example/SM2Kit.java new file mode 100644 index 0000000..2c445a4 --- /dev/null +++ b/src/test/java/example/SM2Kit.java @@ -0,0 +1,136 @@ +package example; + +import com.chakracoin.shsm.logiclayer.BCECUtil; +import com.chakracoin.shsm.logiclayer.SM2Util; +import com.chakracoin.shsm.test.GMBaseTest; +import com.chakracoin.shsm.test.util.FileUtil; +import com.chakracoin.shsm.util.Util; +import org.bouncycastle.crypto.AsymmetricCipherKeyPair; +import org.bouncycastle.crypto.params.ECPrivateKeyParameters; +import org.bouncycastle.crypto.params.ECPublicKeyParameters; +import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey; +import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey; +import org.bouncycastle.math.ec.FixedPointCombMultiplier; +import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; +import org.junit.Assert; +import org.junit.Test; + +import java.nio.charset.StandardCharsets; +import java.security.KeyPair; +import java.util.Base64; + +public class SM2Kit extends GMBaseTest { + + @Test + public void testKeyPairEncoding() { + try { + AsymmetricCipherKeyPair keyPair = SM2Util.generateKeyPairParameter(); + ECPrivateKeyParameters priKey = (ECPrivateKeyParameters) keyPair.getPrivate(); + ECPublicKeyParameters pubKey = (ECPublicKeyParameters) keyPair.getPublic(); + + + System.out.println(Util.bytes2HexString(priKey.getD().toByteArray())); + + byte[] priKeyPkcs8Der = BCECUtil.convertECPrivateKeyToPKCS8(priKey, pubKey); + System.out.println("private key pkcs8 der length:" + priKeyPkcs8Der.length); + System.out.println("private key pkcs8 der:" + ByteUtils.toHexString(priKeyPkcs8Der)); + FileUtil.writeFile("target/ec.pkcs8.pri.der", priKeyPkcs8Der); + + BCECPrivateKey newPriKey = BCECUtil.convertPKCS8ToECPrivateKey(priKeyPkcs8Der); + System.out.println(newPriKey); + + + org.bouncycastle.math.ec.ECPoint q = new FixedPointCombMultiplier().multiply(newPriKey.getParameters().getG(), newPriKey.getD()).normalize(); + ECPublicKeyParameters newPubKey = BCECUtil.createECPublicKeyParameters( + q.getAffineXCoord().toBigInteger().toString(16), + q.getAffineYCoord().toBigInteger().toString(16), + SM2Util.CURVE, SM2Util.DOMAIN_PARAMS + ); + + + byte[] data = "123456789".getBytes(StandardCharsets.UTF_8); + System.out.println("od= " + Util.bytes2HexString(data)); + byte[] sign = SM2Util.sign(newPriKey, data); + System.out.println(Util.bytes2HexString(sign)); + boolean flag = SM2Util.verify(newPubKey, data, sign); + if (!flag) { + Assert.fail("verify failed"); + } + + + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(); + } + } + + + private static final String PK_MARK_HEAD = "-----BEGIN ECDSA PUBLIC KEY-----"; + private static final String PK_MARK_TAIL = "-----END ECDSA PUBLIC KEY-----"; + + @Test + public void pk() { + String data = "592B5E2D7AFEF43552D02A4630A78BBA316A13D0D0C341C595004B2B5CFB25BA11-----BEGIN ECDSA PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEAxNwJKcYPJNzAexpc1a5HdpMP1TlZHcja/kAlbq0fSC5m/efIlH28IfV79MFds9yNajGOJffqG2ngIIuRaOooQ==-----END ECDSA PUBLIC KEY-----"; + String pk = "-----BEGIN ECDSA PUBLIC KEY-----MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEAxNwJKcYPJNzAexpc1a5HdpMP1TlZHcja/kAlbq0fSC5m/efIlH28IfV79MFds9yNajGOJffqG2ngIIuRaOooQ==-----END ECDSA PUBLIC KEY-----"; + String sign = "MEUCIQDy+6Ge95Pv5qQWeO8/ooQB5vLp+cEP3KnyvRz3gvGS2wIgWuWZGI42NH1o0Ti2QhJTwAdNnNwvbbxBDwqt7ECtRfQ="; + + if (pk.startsWith(PK_MARK_HEAD) && pk.endsWith(PK_MARK_TAIL)) { + pk = pk.substring(PK_MARK_HEAD.length(), pk.length() - PK_MARK_TAIL.length()); + pk = pk.trim(); + } + + // 3059301306072A8648CE3D020106082A811CCF5501822D03420004EB1F1EC734D710C016B171C4A0DC5418BD9AE89EEFE8DA7C36D7192B40F8CF9B80EFF7D62F98A9D84BF910B85AD8F2F19D8DC1EE61458A01B7FB21C1850C7290 + System.out.println(pk); + + + // EB1F1EC734D710C016B171C4A0DC5418BD9AE89EEFE8DA7C36D7192B40F8CF9B80EFF7D62F98A9D84BF910B85AD8F2F19D8DC1EE61458A01B7FB21C1850C7290 + byte[] pkHex = Base64.getDecoder().decode(pk.getBytes(StandardCharsets.UTF_8)); + String pkDer = Util.bytes2HexString(pkHex); + pkDer = pkDer.substring(pkDer.indexOf("03420004") + 8); + String xHex = pkDer.substring(0, 64); + String yHex = pkDer.substring(64); + + System.out.println("x=" + xHex); + System.out.println("y=" + yHex); + ECPublicKeyParameters pubKey = BCECUtil.createECPublicKeyParameters(xHex, yHex, SM2Util.CURVE, SM2Util.DOMAIN_PARAMS); + + + byte[] s = Util.decodeBase64( sign ); + System.out.println( Util.bytes2HexString( s ) ); + + + byte[] d = data.getBytes(); + System.out.println("data=" + Util.bytes2HexString(d) ); + boolean flag = SM2Util.verify(pubKey, data.getBytes(), s); + + System.out.println(flag); + + } + + // 3044 + // 0220 + // 09B9756BA1C3CF45745E0AC9EF5A4AC0B77DB7DC9DA79728B8328AF7DB68689E + // 0220 + // 4D90EF145087C4488494551ECEE76F8A0DC057C4CCBB10ACD6D2DC3C04F652A4 + + + @Test + public void testGenerateBCECKeyPair() { + try { + KeyPair keyPair = SM2Util.generateKeyPair(); + ECPrivateKeyParameters priKey = BCECUtil.convertPrivateKeyToParameters((BCECPrivateKey) keyPair.getPrivate()); + ECPublicKeyParameters pubKey = BCECUtil.convertPublicKeyToParameters((BCECPublicKey) keyPair.getPublic()); + + byte[] sign = SM2Util.sign(priKey, SRC_DATA); + boolean flag = SM2Util.verify(pubKey, SRC_DATA, sign); + if (!flag) { + Assert.fail("verify failed"); + } + } catch (Exception ex) { + ex.printStackTrace(); + Assert.fail(); + } + } + + +} diff --git a/src/test/java/example/SM2Result.java b/src/test/java/example/SM2Result.java new file mode 100644 index 0000000..5af0366 --- /dev/null +++ b/src/test/java/example/SM2Result.java @@ -0,0 +1,25 @@ +package example; + +import java.math.BigInteger; + +import org.bouncycastle.math.ec.ECPoint; + +public class SM2Result +{ + public SM2Result() { + } + + // ǩ��/��ǩ + public BigInteger r; + public BigInteger s; + public BigInteger R; + + // ��Կ���� + public byte[] sa; + public byte[] sb; + public byte[] s1; + public byte[] s2; + + public ECPoint keyra; + public ECPoint keyrb; +} diff --git a/src/test/java/org/bouncycastle/cms/SydCmsUtil.java b/src/test/java/org/bouncycastle/cms/SydCmsUtil.java new file mode 100644 index 0000000..13d0472 --- /dev/null +++ b/src/test/java/org/bouncycastle/cms/SydCmsUtil.java @@ -0,0 +1,144 @@ +package org.bouncycastle.cms; + +import org.bouncycastle.asn1.*; +import org.bouncycastle.asn1.cms.ContentInfo; +import org.bouncycastle.asn1.cms.EncryptedContentInfo; +import org.bouncycastle.asn1.cms.OriginatorInfo; +import org.bouncycastle.asn1.x509.AlgorithmIdentifier; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + + +public class SydCmsUtil { + + public static Object readContentInfo( + byte[] input) + throws CMSException { + ASN1InputStream is = new ASN1InputStream(input); + Object v = null; + try { + v = is.readObject(); + } catch (IOException e) { + e.printStackTrace(); + } + return v; + } + + + public static Map getEncryptedContentInfo(ASN1Encodable obj){ + Mapmap = new HashMap<>(); + ASN1Sequence seq = ASN1Sequence.getInstance(obj ); + if (seq.size() < 2) + { + throw new IllegalArgumentException("Truncated Sequence Found"); + } + + ASN1ObjectIdentifier contentType = (ASN1ObjectIdentifier)seq.getObjectAt(0); + map.put( "contentType", contentType ); + + AlgorithmIdentifier contentEncryptionAlgorithm = AlgorithmIdentifier.getInstance( + seq.getObjectAt(1)); + + map.put( "contentEncryptionAlgorithm", contentEncryptionAlgorithm ); + + if (seq.size() > 2) + { + ASN1OctetString encryptedContent = ASN1OctetString.getInstance( + (ASN1TaggedObject)seq.getObjectAt(2), false); + map.put( "encryptedContent", encryptedContent ); + } + return map; + } + + public static Map getOriginatorInfo(ASN1TaggedObject obj, + boolean explicit){ + Mapmap = new HashMap<>(); + ASN1Sequence seq = ASN1Sequence.getInstance(obj, explicit); + switch (seq.size()) + { + case 0: // empty + break; + case 1: + ASN1TaggedObject o = (ASN1TaggedObject)seq.getObjectAt(0); + switch (o.getTagNo()) + { + case 0 : + ASN1Set certs = ASN1Set.getInstance(o, false); + map.put("certs", certs); + break; + case 1 : + ASN1Set crls = ASN1Set.getInstance(o, false); + map.put("crls", crls); + break; + default: + throw new IllegalArgumentException("Bad tag in OriginatorInfo: " + o.getTagNo()); + } + break; + case 2: + ASN1Set certs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(0), false); + map.put("certs", certs); + ASN1Set crls = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(1), false); + map.put("crls", crls); + break; + default: + throw new IllegalArgumentException("OriginatorInfo too big"); + } + + return map; + } + + public static CMSEnvelopedData getCMSEnvelopedData( byte[] input ) throws CMSException { + ContentInfo content = getContentInfo( input ); + return new CMSEnvelopedData(content); + } + + public static ContentInfo getContentInfo( byte[] input ) throws CMSException { + Object content = readContentInfo( input ); + ASN1Sequence seq = ASN1Sequence.getInstance( content ); + return new ContentInfo(seq); + } + + public static Map readCmsInfo( byte[] input ) throws CMSException { + Mapmap = new HashMap<>(); + + Object content = readContentInfo( input ); + ASN1Sequence seq = ASN1Sequence.getInstance( content ); + ASN1ObjectIdentifier oid = (ASN1ObjectIdentifier) seq.getObjectAt(0); + map.put("oid", oid); + + seq = ASN1Sequence.getInstance((ASN1TaggedObject) seq.getObjectAt(1), true); + + int index = 0; + + ASN1Integer version = (ASN1Integer)seq.getObjectAt(index++); + map.put( "version", version ); + + Object tmp = seq.getObjectAt(index++); + + if (tmp instanceof ASN1TaggedObject) + { + OriginatorInfo originatorInfo = OriginatorInfo.getInstance((ASN1TaggedObject)tmp, false); +// MaporiginatorInfo = getOriginatorInfo((ASN1TaggedObject)tmp, false); + map.put( "originatorInfo", originatorInfo ); + tmp = seq.getObjectAt(index++); + } + + ASN1Set recipientInfos = ASN1Set.getInstance(tmp); + map.put( "recipientInfos", recipientInfos ); + + EncryptedContentInfo encryptedContentInfo = EncryptedContentInfo.getInstance( seq.getObjectAt(index++) ); +// Map encryptedContentInfo = getEncryptedContentInfo(seq.getObjectAt(index++)); + map.put( "encryptedContentInfo", encryptedContentInfo ); + + if(seq.size() > index) + { + ASN1Set unprotectedAttrs = ASN1Set.getInstance((ASN1TaggedObject)seq.getObjectAt(index), false); + map.put( "unprotectedAttrs", unprotectedAttrs ); + } + + return map; + } + +} diff --git a/src/test/java/p12/StoreRSAKeyPairInPKCS12.java b/src/test/java/p12/StoreRSAKeyPairInPKCS12.java new file mode 100644 index 0000000..999f151 --- /dev/null +++ b/src/test/java/p12/StoreRSAKeyPairInPKCS12.java @@ -0,0 +1,74 @@ +package p12; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Calendar; +import java.util.Date; + +import org.bouncycastle.asn1.x500.X500Name; +import org.bouncycastle.cert.CertIOException; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder; +import org.bouncycastle.operator.ContentSigner; +import org.bouncycastle.operator.OperatorCreationException; +import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; +import org.bouncycastle.util.encoders.Hex; + +public class StoreRSAKeyPairInPKCS12 { + + public static void main(String[] args) throws Exception { + + // --- generate a key pair (you did this already it seems) + KeyPairGenerator rsaGen = KeyPairGenerator.getInstance("RSA"); + final KeyPair pair = rsaGen.generateKeyPair(); + + // --- create the self signed cert + Certificate cert = createSelfSigned(pair); + + // --- create a new pkcs12 key store in memory + KeyStore pkcs12 = KeyStore.getInstance("PKCS12"); + pkcs12.load(null, null); + + // --- create entry in PKCS12 + pkcs12.setKeyEntry("privatekeyalias", pair.getPrivate(), "entrypassphrase".toCharArray(), new Certificate[] {cert}); + + // --- store PKCS#12 as file + try (FileOutputStream p12 = new FileOutputStream("mystore.p12")) { + pkcs12.store(p12, "p12passphrase".toCharArray()); + } + + // --- read PKCS#12 as file + KeyStore testp12 = KeyStore.getInstance("PKCS12"); + try (FileInputStream p12 = new FileInputStream("mystore.p12")) { + testp12.load(p12, "p12passphrase".toCharArray()); + } + + // --- retrieve private key + System.out.println(Hex.toHexString(testp12.getKey("privatekeyalias", "entrypassphrase".toCharArray()).getEncoded())); + } + + private static X509Certificate createSelfSigned(KeyPair pair) throws OperatorCreationException, CertIOException, CertificateException { + X500Name dnName = new X500Name("CN=publickeystorageonly"); + BigInteger certSerialNumber = BigInteger.ONE; + + Date startDate = new Date(); // now + + Calendar calendar = Calendar.getInstance(); + calendar.setTime(startDate); + calendar.add(Calendar.YEAR, 1); + Date endDate = calendar.getTime(); + + ContentSigner contentSigner = new JcaContentSignerBuilder("SHA256WithRSA").build(pair.getPrivate()); + JcaX509v3CertificateBuilder certBuilder = new JcaX509v3CertificateBuilder(dnName, certSerialNumber, startDate, endDate, dnName, pair.getPublic()); + + return new JcaX509CertificateConverter().getCertificate(certBuilder.build(contentSigner)); + } + +} diff --git a/src/test/resources/dm/dm1.p7 b/src/test/resources/dm/dm1.p7 new file mode 100644 index 0000000..118287c --- /dev/null +++ b/src/test/resources/dm/dm1.p7 @@ -0,0 +1 @@ +MIIBTQYJKoZIhvcNAQcDoIIBPjCCAToCAQAxgfcwgfQCAQAwZTBcMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRswGQYDVQQDDBJDRkNBIFRFU1QgU00yIE9DQTECBRAEKCRSMAsGCSqBHM9VAYItAwR7MHkCIDw69TUwfaVI2gLArRcdK8JNIkcrQuXhdfyvLFzTC1RDAiEA7VPnWU81/6zrV/BYmBI/eOWy0EXMR9iUzS57001m2h0EIBS9cfjNqXKQk6fMOR4gCcXV8AdYbC6/tVvBdabovaM+BBBKuCUQv93U/uecPxB9b3+UMDsGCiqBHM9VBgEEAgEwGwYHKoEcz1UBaAQQAAAAAAAAAAAAAAAAAAAAAIAQn9PUM42xnmcswWKvW5sD6Q== \ No newline at end of file diff --git a/src/test/resources/dm/dm2.p7 b/src/test/resources/dm/dm2.p7 new file mode 100644 index 0000000..8301b14 --- /dev/null +++ b/src/test/resources/dm/dm2.p7 @@ -0,0 +1 @@ +MIAGCSqGSIb3DQEHA6CAMIIBOQIBADGB9jCB8wIBADBlMFwxCzAJBgNVBAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGzAZBgNVBAMMEkNGQ0EgVEVTVCBTTTIgT0NBMQIFEAQoJFIwCwYJKoEcz1UBgi0DBHoweAIgFjDYhEx1ijvlTTPiBxTxAad4eEVfJ+OgOX3DcHS0vssCIGLlasDq1LCU/gVbRkagqbfmWVzetjtIeX025WBAIHOCBCCHNIDD2uHw3KsasXn9ORffzjoZT96t2s3nKA0fIqLzFwQQRUMx/0Iyswr46hDw8s6CdjA7BgoqgRzPVQYBBAIBMBsGByqBHM9VAWgEEAAAAAAAAAAAAAAAAAAAAACAEMkX1B4t04+jB/lIugFX1s0AAAAA diff --git a/src/test/resources/x509/c3.crt b/src/test/resources/x509/c3.crt new file mode 100644 index 0000000..6aeb225 --- /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..1092f67 --- /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/c6.crt b/src/test/resources/x509/c6.crt new file mode 100644 index 0000000..6b910e3 --- /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----- diff --git a/src/test/resources/x509/c7.crt b/src/test/resources/x509/c7.crt new file mode 100644 index 0000000..a0e2b1b --- /dev/null +++ b/src/test/resources/x509/c7.crt @@ -0,0 +1,3 @@ +-----BEGIN CERTIFICATE----- +MIICfDCCAiGgAwIBAgIIEAAAAAFWX4IwDAYIKoEcz1UBg3UFADAfMQswCQYDVQQGEwJDTjEQMA4GA1UEAwwHY2EtdGVzdDAeFw0yNDExMTUwMjM4MjhaFw0yNTExMTUwMjM4MjhaMDUxDzANBgNVBAMMBjE4MDIyMzEVMBMGA1UECgwMc3VueWFyZF9zb2Z0MQswCQYDVQQGEwJDTjBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNT1Hfx8QpYYHqcupxRCLzNIYXnWyo2yiW3FfjLqkIhD1GeJU/rCowpeY5O0lVjF2GqPBySbpNByRZcU1fL+5jijggEtMIIBKTAdBgNVHQ4EFgQUQxeGo3z1UdCK+kHjZquYuNmNuvMwHwYDVR0jBBgwFoAU1NekO2mKPuxPlJnjkFfeZ+Gpjv0wCwYDVR0PBAQDAgbAMIHLBgNVHR8EgcMwgcAwY6A8oDqGOGxkYXA6Ly8yMDIuMTAwLjEwOC40MDozODkvY249ZnVsbENybC5jcmwsQ049Y2EtdGVzdCxDPUNOoiOkITAfMQswCQYDVQQGEwJDTjEQMA4GA1UEAwwHY2EtdGVzdDBZoDKgMIYuaHR0cDovLzE5Mi4xNjguMi4xMTQ6ODE4MS9yb290L2Z1bGxDcmwtU00yLmNybKIjpCEwHzELMAkGA1UEBhMCQ04xEDAOBgNVBAMMB2NhLXRlc3QwDAYDVR0TBAUwAwEBADAMBggqgRzPVQGDdQUAA0cAMEQCIGNDzisk22x6PG3irP2zBDDmeygwBq1lmhZG5jmSDrpcAiAViinNX0P4S4wYU/ieBYKhLO7W6p1cODuJcTWnHulV0w== +-----END CERTIFICATE----- \ No newline at end of file