Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Verification on signed data fails #387

Closed
lviggiani opened this issue Dec 1, 2023 · 1 comment
Closed

Verification on signed data fails #387

lviggiani opened this issue Dec 1, 2023 · 1 comment

Comments

@lviggiani
Copy link

Consider the following code

    const data = await Deno.readFile("./README.md");
    const certificate = (await loadPEM("./playground/domain.pem"))[0] as Certificate;
    const privateKey = (await loadPEM("./playground/domain-pkcs8-nocrypt.key", "PRIVATE KEY"))[0] as CryptoKey;

    const signedData = await signData(data.buffer, certificate, privateKey);

    // verify same
    const ok = await signedData.verify({
        signer: 0,
        checkChain: true,
        trustedCerts: [certificate],
        data: data.buffer
    })

    console.log(ok); // false :(

    // verify external signed like this
    // openssl cms -sign -signer domain.pem -inkey domain-pkcs8-nocrypt.key -binary -in README.md -outform der -out signature

    const cms = ContentInfo.fromBER(await Deno.readFile("./playground/signature")) as ContentInfo;
    if (cms.contentType !== ContentInfo.SIGNED_DATA)
        throw new Error("CMS is not Signed Data");

    const signedData1 = new SignedData({ schema: cms.content });

    const ok1 = await signedData1.verify({
        signer: 0,
        checkChain: true,
        trustedCerts: [certificate],
        data: data.buffer
    })

    console.log(ok1); // true

In the first part I sign data and then I verify it against loaded certificate and it FAILS

In the second part I load a generated signature with openssl with same certificate and private key used in the first part and the verification against the loaded certificate is OK. So, since verification method is the same in both examples, I guess my signature method has something wrong. Here is the code for signature creation

export async function signData(data:ArrayBuffer, certificate: Certificate, privateKey: CryptoKey):Promise<SignedData>{
    const cmsSigned = new SignedData({
        encapContentInfo: new EncapsulatedContentInfo({
            eContentType: ContentInfo.DATA,
            //eContent: new ans1js.OctetString({ valueHex: data })
        }),
        signerInfos: [
            new SignerInfo({
                sid: new IssuerAndSerialNumber({
                    issuer: certificate.issuer,
                    serialNumber: certificate.serialNumber
                })
            })
        ],
        certificates: [certificate]
    });

    await cmsSigned.sign(privateKey, 0, "SHA-256", data);
    return cmsSigned;
}

Here is how I load certificate and key:

export async function loadPEM(src:string,
    type: PEMType = "CERTIFICATE" ):Promise<PkiObject[] | CryptoKey[]> {
    const buffer = pvtsutils.BufferSourceConverter.toArrayBuffer(await Deno.readFile(src));
    const binary = pvtsutils.Convert.ToBinary(buffer);
    const bers = decodePEM(binary, type);
    const ret = [];
    switch (type) {
      case "CERTIFICATE":
        return bers.map(ber => Certificate.fromBER(ber) as Certificate);
      case "PRIVATE KEY":
        for( const ber of bers) 
            ret.push(await crypto.importKey("pkcs8", ber, {
                name: "RSA-PSS",
                hash: "SHA-256",
                },
                true,
                ["sign"]));
        return ret;
      case "PUBLIC KEY":
        return bers.map(ber => PublicKeyInfo.fromBER(ber) as PublicKeyInfo);
    }
    
}
@lviggiani
Copy link
Author

ok, the problem was the algorithm used while importing the key.
By using RSASSA-PKCS1-v1_5 it now works:

crypto.importKey("pkcs8", ber, {
        name: "RSASSA-PKCS1-v1_5",
        hash: "SHA-256"
    },
    true,
    ["sign"])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant