Web API di crittografia non supporta PKCS # 12. È possibile utilizzare una libreria di terze parti per decodificare il p12 come forgiare https://github.com/digitalbazaar/forge#pkcs12 e del carico PrivateKey in webcrypto
Leggendo il certificato PKCS # 12
PKCS # 12 è memorizzato in DER, così abeti t leggerlo da un file o utilizzare un pre-memorizzati Base64
//Reading certificate from a 'file' form field
var reader = new FileReader();
reader.onload = function(e) {
var contents = e.target.result;
var pkcs12Der = arrayBufferToString(contents)
var pkcs12B64 = forge.util.encode64(pkcs12Der);
//do something else...
}
reader.readAsArrayBuffer(file);
function arrayBufferToString(buffer) {
var binary = '';
var bytes = new Uint8Array(buffer);
var len = bytes.byteLength;
for (var i = 0; i < len; i++) {
binary += String.fromCharCode(bytes[ i ]);
}
return binary;
}
//p12 certificate stored in Base64 format
var pkcs12Der= forge.util.decode64(pkcs12B64);
Decodifica PKCS # 12 con la forgia e estrarre chiave
Poi decodificare formato privato DER a ASN1, e lasciare che forgia legge il contenuto
var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der);
var pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password);
quindi ottenere la chiave privata dal pkcs12
del certificato desiderato (vedi forgiare doc) e convertire in PKCS # 8 per essere importato con webcrypto
// load keypair and cert chain from safe content(s)
for(var sci = 0; sci < pkcs12.safeContents.length; ++sci) {
var safeContents = pkcs12.safeContents[sci];
for(var sbi = 0; sbi < safeContents.safeBags.length; ++sbi) {
var safeBag = safeContents.safeBags[sbi];
// this bag has a private key
if(safeBag.type === forge.pki.oids.keyBag) {
//Found plain private key
privateKey = safeBag.key;
} else if(safeBag.type === forge.pki.oids.pkcs8ShroudedKeyBag) {
// found encrypted private key
privateKey = safeBag.key;
} else if(safeBag.type === forge.pki.oids.certBag) {
// this bag has a certificate...
}
}
}
Converti in PKCS # 8
function _privateKeyToPkcs8(privateKey) {
var rsaPrivateKey = forge.pki.privateKeyToAsn1(privateKey);
var privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey);
var privateKeyInfoDer = forge.asn1.toDer(privateKeyInfo).getBytes();
var privateKeyInfoDerBuff = stringToArrayBuffer(privateKeyInfoDer);
return privateKeyInfoDerBuff;
}
function stringToArrayBuffer(data){
var arrBuff = new ArrayBuffer(data.length);
var writer = new Uint8Array(arrBuff);
for (var i = 0, len = data.length; i < len; i++) {
writer[i] = data.charCodeAt(i);
}
return arrBuff;
}
chiave Importa in Webcrypto
E infine importare la chiave nella webcrypto
function _importCryptoKeyPkcs8(privateKey,extractable) {
var privateKeyInfoDerBuff = _privateKeyToPkcs8(privateKey);
//Import the webcrypto key
return crypto.subtle.importKey(
'pkcs8',
privateKeyInfoDerBuff,
{ name: "RSASSA-PKCS1-v1_5", hash:{name:"SHA-256"}},
extractable,
["sign"]);
}
_importCryptoKeyPkcs8(entry.privateKey,extractable).
then(function(cryptoKey) {
//your cryptokey is here!!!
});
Firma digitale
Con il cryptoKey importato restituito dal metodo precedente è possibile firmare con webcrypto.
var digestToSign = forge.util.decode64(digestToSignB64);
var digestToSignBuf = stringToArrayBuffer(digestToSign);
crypto.subtle.sign(
{name: "RSASSA-PKCS1-v1_5"},
cryptoKey,
digestToSignBuf)
.then(function(signature){
signatureB64 = forge.util.encode64(arrayBufferToString(signature))
});
includo codifica da Base64 perché conversioni di dati non sono banali
In pkc12 si ha anche la catena di certificazione, se avete bisogno di costruire formati avanzati come AdES
Al momento WebCrypto non è ancora pronto per cose del genere –
@Eugene Mayevski 'EldoS Corp, ok, pkcs8 è, thx – lumee