11

Próbuję podpisać dane za pomocą interfejsu API WebCrypto, ale zamiast tworzyć klucz prywatny/publiczny i eksportować go do pkcs # 1 lub 8, naprawdę bym lubię używać PKCS # 12 użytkownika do podpisywania danych. Czytałem specyfikację W3C, ale nie mogę zrobić wiele z tego i nie mogę znaleźć żadnego dobrego materiału, jak to zrobić. Teraz chcę odłożyć na bok aplety ActiveX i Java. Czy istnieje sposób na ulepszenie następującego:Jak załadować cyfrowy certyfikat PKCS # 12 z JavaScript WebCrypto API

var buffer = encode(prompt("Please enter your password")); 
    //TODO: 
    //implement a prompt for a pfx or cert 

    return crypto.subtle.importKey("raw", buffer, "PBKDF2", false, usages); 
    //TODO: 
    //instead of importing it, ask for the certificate's pass to sign data 
    //with crypto.subtle.sign 

Jakieś wskazówki?

UPDATE Oto kod pracuję

<script src="forge.min.js"></script> 

<script> 
    var errorsReportedByVerifier; 
    errorsReportedByVerifier = checkStorage() && checkBrowserAPIs(); 
    if (!errorsReportedByVerifier){ 
     console.log("adding click event"); 
     document.getElementById('btnPfx').addEventListener('click', handlePFXFile, false); 
     storeVariables(); 
     getVariables(); 
    } 


    function handlePFXFile(evnt) { 
     console.log("handling pfx") 
     //alert(document.getElementById('pfx').value); 

     //error happens in 1st line 
     //error object does not accept property replace 
     //forge.min.js Line 1, Column: 17823 
     var p12Der = forge.util.decode64(document.getElementById('pfx').valueOf()); 
     //var pkcs12Asn1 = forge.asn1.fromDer(p12Der); 
     //var pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, 'pss'); 
     console.log("pkcs12"); 
    } 
</script> 
+0

Obecnie WebCrypto nie jest jeszcze gotowy za takie rzeczy. –

+0

@Eugene Mayevski 'EldoS Corp, ok, pkcs8 to jest, thx – lumee

Odpowiedz

8

Web kryptografii api nie obsługuje PKCS # 12. Można korzystać z biblioteki strony trzeciej do dekodowania p12 jako kuźnia https://github.com/digitalbazaar/forge#pkcs12 i PrivateKey obciążenia w webcrypto

Czytając certyfikatu PKCS # 12

PKCS # 12 jest przechowywana w DER, więc jodły t odczytać z pliku lub użyć wstępnie przechowywane 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); 

Decode PKCS # 12 z kuźni i wyodrębnić klucza prywatnego

Następnie dekodowania formatu DER do ASN1 i niech Forge odczytuje zawartość

var pkcs12Asn1 = forge.asn1.fromDer(pkcs12Der); 
var pkcs12 = forge.pkcs12.pkcs12FromAsn1(pkcs12Asn1, false, password); 

Następnie dostać klucz prywatny z pkcs12 żądanego świadectwa (patrz wykuć doc) i konwertować do PKCS # 8 być importowane z 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...   
     } 
    } 
} 

Konwersja do 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; 
    } 

przycisk Importuj w Webcrypto

I wreszcie zaimportować klucz w 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!!! 
     }); 

cyfrowy podpis

Zaimportowany klucz cryptoKey zwrócony z powyższej metody można podpisać za pomocą 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)) 
}); 

I obejmują kodowanie z base64 ponieważ konwersja danych nie są trywialne

W pkc12 masz również łańcuch certyfikacji, jeśli trzeba budować zaawansowanych formatów jak zaawansowanym podpisie

+0

Czy istnieje szablon HTML hss + css, który muszę przestrzegać w bibliotece Kuźni. Otrzymuję komunikat o błędzie: "Uncaught TypeError: Can not read property" Class "nieokreślonego pkcs12.js: 109" – lumee

+0

także: util.js: 1569 Uncaught TypeError: input.replace nie jest funkcją util.js.1569 i kilkoma innymi błędami. Pobrałem najnowszą wersję z github – lumee

+0

Forge to czysty javascript. Nie potrzebujesz html ani css. Zbudowałeś minified .js? Nie importuj plików źródłowych jeden po drugim, ponieważ są zależnościami. Proszę również podać szczegóły kodu, który wykonujecie. – pedrofb