同步代码
This commit is contained in:
BIN
Binary file not shown.
Binary file not shown.
@@ -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>
|
||||||
@@ -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 )
|
||||||
Generated
+28
@@ -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=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
@@ -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
Binary file not shown.
@@ -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-----
|
||||||
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-----
|
||||||
@@ -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-----
|
||||||
@@ -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-----
|
||||||
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
docker run -it --rm --workdir /app -v %cd%/:/app ubuntu bash
|
||||||
@@ -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-----
|
||||||
Binary file not shown.
@@ -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-----
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because one or more lines are too long
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
@@ -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");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
@@ -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();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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( );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 ";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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());
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
// }
|
||||||
|
//}
|
||||||
@@ -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");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package example;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
import org.bouncycastle.math.ec.ECPoint;
|
||||||
|
|
||||||
|
public class SM2Result
|
||||||
|
{
|
||||||
|
public SM2Result() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// ǩ��/��ǩ
|
||||||
|
public BigInteger r;
|
||||||
|
public BigInteger s;
|
||||||
|
public BigInteger R;
|
||||||
|
|
||||||
|
// ��Կ����
|
||||||
|
public byte[] sa;
|
||||||
|
public byte[] sb;
|
||||||
|
public byte[] s1;
|
||||||
|
public byte[] s2;
|
||||||
|
|
||||||
|
public ECPoint keyra;
|
||||||
|
public ECPoint keyrb;
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
MIIBTQYJKoZIhvcNAQcDoIIBPjCCAToCAQAxgfcwgfQCAQAwZTBcMQswCQYDVQQGEwJDTjEwMC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRswGQYDVQQDDBJDRkNBIFRFU1QgU00yIE9DQTECBRAEKCRSMAsGCSqBHM9VAYItAwR7MHkCIDw69TUwfaVI2gLArRcdK8JNIkcrQuXhdfyvLFzTC1RDAiEA7VPnWU81/6zrV/BYmBI/eOWy0EXMR9iUzS57001m2h0EIBS9cfjNqXKQk6fMOR4gCcXV8AdYbC6/tVvBdabovaM+BBBKuCUQv93U/uecPxB9b3+UMDsGCiqBHM9VBgEEAgEwGwYHKoEcz1UBaAQQAAAAAAAAAAAAAAAAAAAAAIAQn9PUM42xnmcswWKvW5sD6Q==
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
MIAGCSqGSIb3DQEHA6CAMIIBOQIBADGB9jCB8wIBADBlMFwxCzAJBgNVBAYTAkNOMTAwLgYDVQQKDCdDaGluYSBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxGzAZBgNVBAMMEkNGQ0EgVEVTVCBTTTIgT0NBMQIFEAQoJFIwCwYJKoEcz1UBgi0DBHoweAIgFjDYhEx1ijvlTTPiBxTxAad4eEVfJ+OgOX3DcHS0vssCIGLlasDq1LCU/gVbRkagqbfmWVzetjtIeX025WBAIHOCBCCHNIDD2uHw3KsasXn9ORffzjoZT96t2s3nKA0fIqLzFwQQRUMx/0Iyswr46hDw8s6CdjA7BgoqgRzPVQYBBAIBMBsGByqBHM9VAWgEEAAAAAAAAAAAAAAAAAAAAACAEMkX1B4t04+jB/lIugFX1s0AAAAA
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIHGAgECBIHA/FjfJkcNPEqGRLtdEV2k2TTszxsBf6KzZM02wxJ+tQJqEHGjxSv61CckxcdSS8J3KnsVmKHmfhlB4qNiB+l2WX9aqN2SYKugBqPm5yujgg+MIjvseK3aHJv1RKzdlY99lk/foF64Xoqev4yrb/1QlULTKTmXxBWvHy8eDqmmrK61WNDNwRpQkblU8+m1jpcYO6pYZ7FhhyIwSFfgton/0YqaEuFko0shZT+N5Uo+8Xj9Si+klf1g0ZkXyLBvu2BK
|
||||||
|
-----END CERTIFICATE-----
|
||||||
@@ -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-----
|
||||||
@@ -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-----
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICfDCCAiGgAwIBAgIIEAAAAAFWX4IwDAYIKoEcz1UBg3UFADAfMQswCQYDVQQGEwJDTjEQMA4GA1UEAwwHY2EtdGVzdDAeFw0yNDExMTUwMjM4MjhaFw0yNTExMTUwMjM4MjhaMDUxDzANBgNVBAMMBjE4MDIyMzEVMBMGA1UECgwMc3VueWFyZF9zb2Z0MQswCQYDVQQGEwJDTjBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABNT1Hfx8QpYYHqcupxRCLzNIYXnWyo2yiW3FfjLqkIhD1GeJU/rCowpeY5O0lVjF2GqPBySbpNByRZcU1fL+5jijggEtMIIBKTAdBgNVHQ4EFgQUQxeGo3z1UdCK+kHjZquYuNmNuvMwHwYDVR0jBBgwFoAU1NekO2mKPuxPlJnjkFfeZ+Gpjv0wCwYDVR0PBAQDAgbAMIHLBgNVHR8EgcMwgcAwY6A8oDqGOGxkYXA6Ly8yMDIuMTAwLjEwOC40MDozODkvY249ZnVsbENybC5jcmwsQ049Y2EtdGVzdCxDPUNOoiOkITAfMQswCQYDVQQGEwJDTjEQMA4GA1UEAwwHY2EtdGVzdDBZoDKgMIYuaHR0cDovLzE5Mi4xNjguMi4xMTQ6ODE4MS9yb290L2Z1bGxDcmwtU00yLmNybKIjpCEwHzELMAkGA1UEBhMCQ04xEDAOBgNVBAMMB2NhLXRlc3QwDAYDVR0TBAUwAwEBADAMBggqgRzPVQGDdQUAA0cAMEQCIGNDzisk22x6PG3irP2zBDDmeygwBq1lmhZG5jmSDrpcAiAViinNX0P4S4wYU/ieBYKhLO7W6p1cODuJcTWnHulV0w==
|
||||||
|
-----END CERTIFICATE-----
|
||||||
Reference in New Issue
Block a user