我在数字签名和xadesjs
方面有一个问题。我正在node.js中编写一台小服务器,该服务器应加密使用Xades的XML文件。我有一个PFX文件,我将其导出到PEM和PK8格式。一般问题是,当我使用xadesjs
生成按键时,一切正常。这是一个例子:
// Generate RSA key pair
let privateKey, publicKey;
XAdES.Application.crypto.subtle.generateKey(
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 1024, //can be 1024, 2048, or 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: { name: "SHA-256" }, //can be "SHA-1", "SHA-256", "SHA-384", or "SHA-512"
},
false, //whether the key is extractable (i.e. can be used in exportKey)
["sign", "verify"] //can be any combination of "sign" and "verify"
)
.then(function (keyPair) {
privateKey = keyPair.privateKey;
// Call sign function
return SignXml(xmlString, privateKey,
{ name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" } });
})
.then(function (signedDocument) {
console.log("Signed document:nn", signedDocument);
next(null, signedDocument);
})
.catch(function (e) {
console.log(e);
next(e, null);
});
,但我可能一直在使用所有可能的组合来获取importKey
方法的工作。例如,即使密钥在pkcs8中(用openSSL导出),这也不起作用:
let key = fs.readFileSync("key.pem");
XAdES.Application.crypto.subtle.importKey("pkcs8", key,
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048, //can be 1024, 2048, or 4096,
publicExponent: new Uint8Array([1, 0, 1]),
hash: { name: "SHA-256" },
},
false,
["sign"]
)
.then(function (privateKey) {
// Call sign function
return SignXml(xmlString, privateKey,
{ name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" } });
})
我有一个错误:
Error: ImportKey: Can not import key for pkcs8
我的主要目标是获取一个程序,我可以在其中指定通往数字签名的路径,而我的程序将导入密钥和证书,并最终与它们一起签名我的文件。如果所有内容都可以存储在PFX文件中,那还是很舒服的,但是即使您有任何解决方案,即使键和证书是单独存储的(PEM和PK8),我也会很感激。
如果任何人都有相同的问题。这是在@pedrofb的答案的帮助下实现的。
首先,我在pem
NPM软件包的帮助下获得了密钥和证书。然后,我卸下标题和页脚,然后将钥匙转换为阵列:
const pfx = fs.readFileSync("cert.pfx");
pem.readPkcs12(pfx, { p12Password: "test123" }, (err: any, cert: any) => {
if(err) return console.log(err);
let privateKey = b64ToBinary(removePFXComments(cert.key));
let certificate = removePFXComments(cert.cert);
这是以上两种使用方法的实现:
function removePFXComments(pem) {
let lines = pem.split('n');
let encoded = '';
for (let i = 0; i < lines.length; i++) {
if (lines[i].trim().length > 0 &&
lines[i].indexOf('-----BEGIN CERTIFICATE-----') < 0 &&
lines[i].indexOf('-----END CERTIFICATE') < 0 &&
lines[i].indexOf('-----BEGIN RSA PRIVATE KEY-----') < 0 &&
lines[i].indexOf('-----BEGIN RSA PUBLIC KEY-----') < 0 &&
lines[i].indexOf('-----BEGIN PUBLIC KEY-----') < 0 &&
lines[i].indexOf('-----END PUBLIC KEY-----') < 0 &&
lines[i].indexOf('-----BEGIN PRIVATE KEY-----') < 0 &&
lines[i].indexOf('-----END PRIVATE KEY-----') < 0 &&
lines[i].indexOf('-----END RSA PRIVATE KEY-----') < 0 &&
lines[i].indexOf('-----END RSA PUBLIC KEY-----') < 0) {
encoded += lines[i].trim();
}
}
return encoded;
}
function b64ToBinary(base64) {
let raw = atob(base64);
let rawLength = raw.length;
let array = new Uint8Array(new ArrayBuffer(rawLength));
for(let i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
return array;
}