PeculiarVentures / node-webcrypto-p11

A WebCrypto Polyfill for Node in typescript built on PKCS#11.
MIT License
44 stars 15 forks source link

Generating RSA keypair and then saving the keys sets algorithm hash to SHA-256 #48

Closed schoolmeister closed 2 years ago

schoolmeister commented 5 years ago

Issue

No matter which hashing algorithm is filled in when generating an RSA keypair, after saving it to the keyStore and retrieving it again, the hashing algorithm is always set to SHA-256. Using such a corrupt key for encryption/decryption raises a CKR_ARGUMENTS_BAD:7 error.

Temporary workaround

After retrieving, manually setting algorithm.hash.name to SHA-1 seems to fix the error.

Example code

let keys = await crypto.subtle.generateKey({
        name:"RSA-OAEP",
        modulusLength: 2048,
        publicExponent: new Uint8Array([1, 0, 1]),
        hash: {
            name: "SHA-1"
        }},
    true,
    ["encrypt", "decrypt"]
);
// algorithm.hash.name will be SHA-1
console.log(keys.publicKey);
// save to and retrieve key from storage
const publicKeyID = await crypto.keyStorage.setItem(keys.publicKey);
let pubkey = await crypto.keyStorage.getItem(publicKeyID);
// algorithm.hash.name will be SHA-256
console.log(pubkey);
// try to encrypt something, raises CKR_ARGUMENTS_BAD:7 error
let alg = { name: "RSA-OAEP" };
crypto.subtle.encrypt(alg, pubkey, new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]));
rmhrisk commented 5 years ago

@schoolmeister, unfortunately, PKCS#11 does not inherently save the algorithm used in key generation or have a way to specify how a key was generated.

WebCrypto requires that the caller specify the hash algorithm to be specified on generation and import.

It is technically possible in the PKCS#11 specification to set properties on a key, for example, we could according to the specification set what hash algorithm was used as a property. This would be proprietary as there is no standard for it but even if we did this many PKCS#11 libraries do not support this.

As a result, we currently hard-code the use of SHA-256 due to security concerns over prolonging the use of SHA-1.

This value can be overridden as is done here.

microshine commented 3 years ago

It's possible to set hash algorithm on key getting using importKey arguments

https://github.com/PeculiarVentures/node-webcrypto-p11/blob/master/src/key_storage.ts#L51

await crypto.keyStorage.getItem(publicKeyID, algorithm, false, ["sign"]);