同步代码
This commit is contained in:
parent
71c4ea0787
commit
478c36fbff
BIN
112233.bin
Normal file
BIN
112233.bin
Normal file
Binary file not shown.
BIN
certificate.pem
Normal file
BIN
certificate.pem
Normal file
Binary file not shown.
34
gmhelper.iml
Normal file
34
gmhelper.iml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: club.fullstack:ddd:1.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.12" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.11.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.8.0-alpha2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.9.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-core:2.9.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.2.4.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.2.4.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.2.4.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.2.4.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.2.4.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.2.4.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.reflections:reflections:0.9.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.guava:guava:20.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.javassist:javassist:3.21.0-GA" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.65" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.65" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
166
js/mac.js
Normal file
166
js/mac.js
Normal file
@ -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 )
|
28
js/package-lock.json
generated
Normal file
28
js/package-lock.json
generated
Normal file
@ -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=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
14
js/package.json
Normal file
14
js/package.json
Normal file
@ -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"
|
||||||
|
}
|
||||||
|
}
|
318
js/sm4.js
Normal file
318
js/sm4.js
Normal file
@ -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) {
|
||||||
|
|
||||||
|
}
|
42
js/test.js
Normal file
42
js/test.js
Normal file
@ -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()
|
BIN
mystore.p12
Normal file
BIN
mystore.p12
Normal file
Binary file not shown.
3
openssl/CN00000001.cer
Normal file
3
openssl/CN00000001.cer
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIIEwDCCA6igAwIBAgIUQEBXtVVl52ZmHiSuJb8flUavGCswDQYJKoZIhvcNAQELBQAwgYkxQzBBBgNVBAMMOlNoZW4gWmhlbiBpVHJ1c0NoaW5hIENsYXNzIEVudGVycHJpc2UgU3Vic2NyaWJlciBDQSAtIFRlc3QxGDAWBgNVBAsMD+a1i+ivlemDqOivleeUqDEbMBkGA1UECgwS5aSp6K+a5a6J5L+h6K+V55SoMQswCQYDVQQGEwJDTjAeFw0yMjEyMDIwNzA4MDNaFw0yMzEyMDIwNzA4MDNaMGExDDAKBgNVBAMMA3N5ZDESMBAGA1UECwwJ5oqA5pyv6YOoMTAwLgYDVQQKDCfkuK3ljZfli5jmtYvorr7orqHnoJTnqbbpmaLmnInpmZDlhazlj7gxCzAJBgNVBAYMAkNOMIIBMzCB7AYHKoZIzj0CATCB4AIBATAsBgcqhkjOPQEBAiEA/////v////////////////////8AAAAA//////////8wRAQg/////v////////////////////8AAAAA//////////wEICjp+p6dn140TVqeS89lCafzl4n1FauPkt28vUFNlA6TBEEEMsSuLB8ZgRlfmQRGajnJlI/jC7/yZgvhcVpFiTNMdMe8Nzai9PZ3nFm9zuNraSFT0KmHfMYqR0AC3zLlITnwoAIhAP////7///////////////9yA99rIcYFK1O79Ak51UEjAgEBA0IABJo9hdPsHOxzwVPBvUZXU6IufmEz6DW0rqBdTylT8uDe4rcCuWjbQ5vYnd+Mvn2WIvApRKL3SLWVXa8xx9x8yDqjggE0MIIBMDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDBqBgNVHS4EYzBhMF+gXaBbhllodHRwOi8vc3p0b3BjYS5zeml0cnVzLmNvbS5jbi9wdWJsaWMvaXRydXNjcmw/Q0E9NjQ5MjhGMDI4Mjc5RUYyNTk3NURBNjhDNUZFNThDQTZFOUU1NEVGRjBqBgNVHR8EYzBhMF+gXaBbhllodHRwOi8vc3p0b3BjYS5zeml0cnVzLmNvbS5jbi9wdWJsaWMvaXRydXNjcmw/Q0E9NjQ5MjhGMDI4Mjc5RUYyNTk3NURBNjhDNUZFNThDQTZFOUU1NEVGRjAfBgNVHSMEGDAWgBTIMh5AEX5B1LtVAa/MRxpCNUar7zAdBgNVHQ4EFgQUixfvAdos9oruLKs/uR6UEQHCVgowDQYJKoZIhvcNAQELBQADggEBAI30brI94+gwx3j5rlhD7l/Sx5t6Y517bkfnYvT1CvrqEPjt43HND3ABn34Wn5Ys0Gyc0dFJJzZB1NGP3agLyQuzeRS5v5YcIn7kDTYPSc8PGS9pEXAwrKcoBza3MrjZhrZxpR9/ZuNH9zS0LFE/nVdly2YC09dS4IyQNi2UPqTxL+Kh0Dr0lC1cfPkBeQIt4mEpKHOgkXIB57ZMlFR5Kk7ygidQuzgNqsG2p7ASRza0wVmWirysx9azk2/QIyz9VCLBzLZV0IUP3F6xSaII9U/ZfmzVPWkAV2Y8mz97KbML9BpCohL41iO6T3ylsQ3kpVFcRyqhBA9B7jxTCx31zSc=
|
||||||
|
-----END CERTIFICATE-----
|
BIN
openssl/IDCTEST4XXX-new.p12
Normal file
BIN
openssl/IDCTEST4XXX-new.p12
Normal file
Binary file not shown.
@ -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-----
|
23
openssl/ca/Shen Zhen iTrusChina Class Root CA - Test.cer
Normal file
23
openssl/ca/Shen Zhen iTrusChina Class Root CA - Test.cer
Normal file
@ -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-----
|
56
openssl/cmtp.cer
Normal file
56
openssl/cmtp.cer
Normal file
@ -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-----
|
BIN
openssl/cmtp.p12
Normal file
BIN
openssl/cmtp.p12
Normal file
Binary file not shown.
1
openssl/env.cmd
Normal file
1
openssl/env.cmd
Normal file
@ -0,0 +1 @@
|
|||||||
|
docker run -it --rm --workdir /app -v %cd%/:/app ubuntu bash
|
18
openssl/sandbox.cer
Normal file
18
openssl/sandbox.cer
Normal file
@ -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-----
|
BIN
openssl/sandbox.p12
Normal file
BIN
openssl/sandbox.p12
Normal file
Binary file not shown.
23
openssl/sandbox.pem
Normal file
23
openssl/sandbox.pem
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
Bag Attributes: <No 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-----
|
BIN
openssl/user.p12
Normal file
BIN
openssl/user.p12
Normal file
Binary file not shown.
BIN
private_key.pem
Normal file
BIN
private_key.pem
Normal file
Binary file not shown.
BIN
protected_file.p7m
Normal file
BIN
protected_file.p7m
Normal file
Binary file not shown.
BIN
public_key.pem
Normal file
BIN
public_key.pem
Normal file
Binary file not shown.
8
sHSM.iml
Normal file
8
sHSM.iml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module version="4">
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="Spring" name="Spring">
|
||||||
|
<configuration />
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
83
src/main/java/com/chakracoin/shsm/util/TripleDESUtil.java
Normal file
83
src/main/java/com/chakracoin/shsm/util/TripleDESUtil.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
src/test/java/Base64De.java
Normal file
17
src/test/java/Base64De.java
Normal file
@ -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 = "MIIHtwYJKoZIhvcNAQcCoIIHqDCCB6QCAQExADALBgkqhkiG9w0BBwGgggeMMIICFDCCAbegAwIBAgIKWAwtBT7Mhdc+uzAMBggqgRzPVQGDdQUAMF0xCzAJBgNVBAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHDAaBgNVBAMME0NGQ0EgVEVTVCBDUyBTTTIgQ0EwHhcNMjAwMzEzMDYwMDAwWhcNMzUwNzA1MDMyODQzWjBdMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRwwGgYDVQQDDBNDRkNBIFRFU1QgQ1MgU00yIENBMFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEtTjB3O4JueYFDDOtxH678HBZbEmrsgd3BDIdGf0BekyA26n9S0/pKPnjBh/zLouS8+GB5EEnjbn4An24yo1Gv6NdMFswHwYDVR0jBBgwFoAUtdiQb1zw2DPSY71+ssONxk8SemEwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFLXYkG9c8Ngz0mO9frLDjcZPEnphMAwGCCqBHM9VAYN1BQADSQAwRgIhAJD0aFyGU+n8eBbWT1OGQsSwKus41ktNo+wv/uP6ikC3AiEAkBWVU0Nk7y3BGSRq7EEj5OKI5m99YEc5KejbO00+MFswggJNMIIB8qADAgECAgpkJNeAvQwo860HMAwGCCqBHM9VAYN1BQAwXTELMAkGA1UEBhMCQ04xMDAuBgNVBAoMJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEcMBoGA1UEAwwTQ0ZDQSBURVNUIENTIFNNMiBDQTAeFw0xMjEyMjUxMjI1MDZaFw0zMjA3MjMxMjI1MDZaMFwxCzAJBgNVBAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGzAZBgNVBAMMEkNGQ0EgVEVTVCBTTTIgT0NBMTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABDO4WAlt51jnm7o1OgkSUZbM9P71QXV3Fyimd6s07d+pF3gLWUPPP0sllJ+YzI1hqTJgL7rOH0br9o9dbU539EWjgZgwgZUwHwYDVR0jBBgwFoAUtdiQb1zw2DPSY71+ssONxk8SemEwDAYDVR0TBAUwAwEB/zA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vMjEwLjc0LjQyLjMvdGVzdHJjYS9TTTIvY3JsMS5jcmwwCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBRr/hjaj0I6prhtsy6Igzo0osEw4TAMBggqgRzPVQGDdQUAA0cAMEQCIBGQOaRDQKWKjjz33ghSzrecDyTrnY7YLj7sRCzVJJu4AiBzA1SscnIRhfzFPkEqX1OUk55/MI00lblnR/dj9KNobTCCAx8wggLEoAMCAQICBRBViTOHMAwGCCqBHM9VAYN1BQAwXDELMAkGA1UEBhMCQ04xMDAuBgNVBAoMJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEbMBkGA1UEAwwSQ0ZDQSBURVNUIFNNMiBPQ0ExMB4XDTIzMDMyNDAyMzEwM1oXDTIzMDYyNDAyMzEwM1owWjELMAkGA1UEBhMCQ04xDzANBgNVBAgMBuWMl+S6rDEPMA0GA1UEBwwG5YyX5LqsMRIwEAYDVQQKDAnkv6Hpm4Xovr4xFTATBgNVBAMMDDE5Mi4xNjguMS4yMzBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNyGR1x7rTS5BmZjolFCKNWFhCtALA5Gq6qP+SALjQa/p+TvlglTAxYJ8clH8aH6JuhlpMFlIxJL+ajqgvTIa6CjggFxMIIBbTAJBgNVHRMEAjAAMD8GCCsGAQUFBwEBBDMwMTAvBggrBgEFBQcwAYYjaHR0cDovL29jc3B0ZXN0LmNmY2EuY29tLmNuOjgwL29jc3AwDwYJKwYBBQUHMAEFBAIFADAdBgNVHREEFjAUggwxOTIuMTY4LjEuMjOHBMCoARcwCwYDVR0PBAQDAgP4MB0GA1UdDgQWBBSv+n7ifYSpfOdhvM9qKZYkhSgH1TAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwHwYDVR0jBBgwFoAUa/4Y2o9COqa4bbMuiIM6NKLBMOEwSAYDVR0gBEEwPzA9BghggRyG7yoBATAxMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmNmY2EuY29tLmNuL3VzL3VzLTE0Lmh0bTA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vdWNybC5jZmNhLmNvbS5jbi9TTTIvY3JsNDc3OTUuY3JsMAwGCCqBHM9VAYN1BQADRwAwRAIgbJKddeGWZOWetIADGebIBTGwWqtrf+9je4MniVdWGXECIDaGtLrmVXkHUMbGZI21ED77ApAg6LdFp9Ry4QOAjnZIMQA=";
|
||||||
|
|
||||||
|
File f = new File("./112233.bin");
|
||||||
|
OutputStream os = new FileOutputStream(f);
|
||||||
|
os.write( Util.decodeBase64( v ) );
|
||||||
|
os.flush();
|
||||||
|
}
|
||||||
|
}
|
18
src/test/java/FileUtil.java
Normal file
18
src/test/java/FileUtil.java
Normal file
File diff suppressed because one or more lines are too long
60
src/test/java/OpenCIPS.java
Normal file
60
src/test/java/OpenCIPS.java
Normal file
@ -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<String> 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
253
src/test/java/RSA.java
Normal file
253
src/test/java/RSA.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
51
src/test/java/RSAEncryptionExample.java
Normal file
51
src/test/java/RSAEncryptionExample.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
145
src/test/java/Renzheng.java
Normal file
145
src/test/java/Renzheng.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
32
src/test/java/Ret.java
Normal file
32
src/test/java/Ret.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
}
|
26
src/test/java/SM2VerificationUtil.java
Normal file
26
src/test/java/SM2VerificationUtil.java
Normal file
@ -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();
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
39
src/test/java/Test.java
Normal file
39
src/test/java/Test.java
Normal file
@ -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");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
84
src/test/java/com/chakracoin/shsm/cert/QPublicKey.java
Normal file
84
src/test/java/com/chakracoin/shsm/cert/QPublicKey.java
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
47
src/test/java/com/chakracoin/shsm/cert/SimplePublicKey.java
Normal file
47
src/test/java/com/chakracoin/shsm/cert/SimplePublicKey.java
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
11
src/test/java/com/chakracoin/shsm/shsm.iml
Normal file
11
src/test/java/com/chakracoin/shsm/shsm.iml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" packagePrefix="com.chakracoin.shsm" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
197
src/test/java/com/chakracoin/shsm/test/CmsApplication.java
Normal file
197
src/test/java/com/chakracoin/shsm/test/CmsApplication.java
Normal file
@ -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<RecipientInformation> 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<X509Certificate> x509CertificateList = new ArrayList<X509Certificate>();
|
||||||
|
// 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<X509CertificateHolder> certificates = cmsSignedData.getCertificates();
|
||||||
|
//
|
||||||
|
// final SignerInformationStore signerInformationStore = cmsSignedData.getSignerInfos();
|
||||||
|
//
|
||||||
|
// final Collection<SignerInformation> signers = signerInformationStore.getSigners();
|
||||||
|
//
|
||||||
|
// final SignerInformation signer = signers.iterator().next();
|
||||||
|
//
|
||||||
|
// final X509CertificateHolder x509CertificateHolder = ((Collection<X509CertificateHolder>) 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();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
58
src/test/java/com/chakracoin/shsm/test/Keytools.java
Normal file
58
src/test/java/com/chakracoin/shsm/test/Keytools.java
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
148
src/test/java/com/chakracoin/shsm/test/PBKDF2Tool.java
Normal file
148
src/test/java/com/chakracoin/shsm/test/PBKDF2Tool.java
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
162
src/test/java/com/chakracoin/shsm/test/PKCS7Test.java
Normal file
162
src/test/java/com/chakracoin/shsm/test/PKCS7Test.java
Normal file
@ -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, Map<String, String>issuer ) 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 );
|
||||||
|
Map<String,String>map = 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( );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
233
src/test/java/com/chakracoin/shsm/test/PKCS7Util.java
Normal file
233
src/test/java/com/chakracoin/shsm/test/PKCS7Util.java
Normal file
@ -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<Certificate> certList = new ArrayList<Certificate>();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
17
src/test/java/com/chakracoin/shsm/test/PKKDF2Test.java
Normal file
17
src/test/java/com/chakracoin/shsm/test/PKKDF2Test.java
Normal file
@ -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 ";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
67
src/test/java/com/chakracoin/shsm/test/SM2KeyUtilTest.java
Normal file
67
src/test/java/com/chakracoin/shsm/test/SM2KeyUtilTest.java
Normal file
@ -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());
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
79
src/test/java/com/chakracoin/shsm/test/t.java
Normal file
79
src/test/java/com/chakracoin/shsm/test/t.java
Normal file
@ -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();
|
||||||
|
// }
|
||||||
|
//}
|
17
src/test/java/com/chakracoin/shsm/test/t2.java
Normal file
17
src/test/java/com/chakracoin/shsm/test/t2.java
Normal file
@ -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");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
136
src/test/java/example/SM2Kit.java
Normal file
136
src/test/java/example/SM2Kit.java
Normal file
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
25
src/test/java/example/SM2Result.java
Normal file
25
src/test/java/example/SM2Result.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package example;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
|
|
||||||
|
public class SM2Result
|
||||||
|
{
|
||||||
|
public SM2Result() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ǩ<EFBFBD><EFBFBD>/<EFBFBD><EFBFBD>ǩ
|
||||||
|
public BigInteger r;
|
||||||
|
public BigInteger s;
|
||||||
|
public BigInteger R;
|
||||||
|
|
||||||
|
// <EFBFBD><EFBFBD>Կ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
public byte[] sa;
|
||||||
|
public byte[] sb;
|
||||||
|
public byte[] s1;
|
||||||
|
public byte[] s2;
|
||||||
|
|
||||||
|
public ECPoint keyra;
|
||||||
|
public ECPoint keyrb;
|
||||||
|
}
|
144
src/test/java/org/bouncycastle/cms/SydCmsUtil.java
Normal file
144
src/test/java/org/bouncycastle/cms/SydCmsUtil.java
Normal file
@ -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<String, Object> getEncryptedContentInfo(ASN1Encodable obj){
|
||||||
|
Map<String, Object>map = 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<String, Object> getOriginatorInfo(ASN1TaggedObject obj,
|
||||||
|
boolean explicit){
|
||||||
|
Map<String, Object>map = 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<String, Object> readCmsInfo( byte[] input ) throws CMSException {
|
||||||
|
Map<String, Object>map = 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);
|
||||||
|
// Map<String, Object>originatorInfo = 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<String, Object> 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
74
src/test/java/p12/StoreRSAKeyPairInPKCS12.java
Normal file
74
src/test/java/p12/StoreRSAKeyPairInPKCS12.java
Normal file
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1
src/test/resources/dm/dm1.p7
Normal file
1
src/test/resources/dm/dm1.p7
Normal file
@ -0,0 +1 @@
|
|||||||
|
MIIBTQYJKoZIhvcNAQcDoIIBPjCCAToCAQAxgfcwgfQCAQAwZTBcMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRswGQYDVQQDDBJDRkNBIFRFU1QgU00yIE9DQTECBRAEKCRSMAsGCSqBHM9VAYItAwR7MHkCIDw69TUwfaVI2gLArRcdK8JNIkcrQuXhdfyvLFzTC1RDAiEA7VPnWU81/6zrV/BYmBI/eOWy0EXMR9iUzS57001m2h0EIBS9cfjNqXKQk6fMOR4gCcXV8AdYbC6/tVvBdabovaM+BBBKuCUQv93U/uecPxB9b3+UMDsGCiqBHM9VBgEEAgEwGwYHKoEcz1UBaAQQAAAAAAAAAAAAAAAAAAAAAIAQn9PUM42xnmcswWKvW5sD6Q==
|
1
src/test/resources/dm/dm2.p7
Normal file
1
src/test/resources/dm/dm2.p7
Normal file
@ -0,0 +1 @@
|
|||||||
|
MIAGCSqGSIb3DQEHA6CAMIIBOQIBADGB9jCB8wIBADBlMFwxCzAJBgNVBAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGzAZBgNVBAMMEkNGQ0EgVEVTVCBTTTIgT0NBMQIFEAQoJFIwCwYJKoEcz1UBgi0DBHoweAIgFjDYhEx1ijvlTTPiBxTxAad4eEVfJ+OgOX3DcHS0vssCIGLlasDq1LCU/gVbRkagqbfmWVzetjtIeX025WBAIHOCBCCHNIDD2uHw3KsasXn9ORffzjoZT96t2s3nKA0fIqLzFwQQRUMx/0Iyswr46hDw8s6CdjA7BgoqgRzPVQYBBAIBMBsGByqBHM9VAWgEEAAAAAAAAAAAAAAAAAAAAACAEMkX1B4t04+jB/lIugFX1s0AAAAA
|
3
src/test/resources/x509/c3.crt
Normal file
3
src/test/resources/x509/c3.crt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIHGAgECBIHA/FjfJkcNPEqGRLtdEV2k2TTszxsBf6KzZM02wxJ+tQJqEHGjxSv61CckxcdSS8J3KnsVmKHmfhlB4qNiB+l2WX9aqN2SYKugBqPm5yujgg+MIjvseK3aHJv1RKzdlY99lk/foF64Xoqev4yrb/1QlULTKTmXxBWvHy8eDqmmrK61WNDNwRpQkblU8+m1jpcYO6pYZ7FhhyIwSFfgton/0YqaEuFko0shZT+N5Uo+8Xj9Si+klf1g0ZkXyLBvu2BK
|
||||||
|
-----END CERTIFICATE-----
|
3
src/test/resources/x509/c4.crt
Normal file
3
src/test/resources/x509/c4.crt
Normal file
@ -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-----
|
17
src/test/resources/x509/c6.crt
Normal file
17
src/test/resources/x509/c6.crt
Normal file
@ -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-----
|
3
src/test/resources/x509/c7.crt
Normal file
3
src/test/resources/x509/c7.crt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICfDCCAiGgAwIBAgIIEAAAAAFWX4IwDAYIKoEcz1UBg3UFADAfMQswCQYDVQQGEwJDTjEQMA4GA1UEAwwHY2EtdGVzdDAeFw0yNDExMTUwMjM4MjhaFw0yNTExMTUwMjM4MjhaMDUxDzANBgNVBAMMBjE4MDIyMzEVMBMGA1UECgwMc3VueWFyZF9zb2Z0MQswCQYDVQQGEwJDTjBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNT1Hfx8QpYYHqcupxRCLzNIYXnWyo2yiW3FfjLqkIhD1GeJU/rCowpeY5O0lVjF2GqPBySbpNByRZcU1fL+5jijggEtMIIBKTAdBgNVHQ4EFgQUQxeGo3z1UdCK+kHjZquYuNmNuvMwHwYDVR0jBBgwFoAU1NekO2mKPuxPlJnjkFfeZ+Gpjv0wCwYDVR0PBAQDAgbAMIHLBgNVHR8EgcMwgcAwY6A8oDqGOGxkYXA6Ly8yMDIuMTAwLjEwOC40MDozODkvY249ZnVsbENybC5jcmwsQ049Y2EtdGVzdCxDPUNOoiOkITAfMQswCQYDVQQGEwJDTjEQMA4GA1UEAwwHY2EtdGVzdDBZoDKgMIYuaHR0cDovLzE5Mi4xNjguMi4xMTQ6ODE4MS9yb290L2Z1bGxDcmwtU00yLmNybKIjpCEwHzELMAkGA1UEBhMCQ04xEDAOBgNVBAMMB2NhLXRlc3QwDAYDVR0TBAUwAwEBADAMBggqgRzPVQGDdQUAA0cAMEQCIGNDzisk22x6PG3irP2zBDDmeygwBq1lmhZG5jmSDrpcAiAViinNX0P4S4wYU/ieBYKhLO7W6p1cODuJcTWnHulV0w==
|
||||||
|
-----END CERTIFICATE-----
|
Loading…
Reference in New Issue
Block a user