Fix ECDSA sign/verify error
This commit is contained in:
parent
feaf3cc798
commit
97c0c5956b
|
@ -19,7 +19,7 @@ export const AsnIntegerWithoutPaddingConverter: IAsnConverter<ArrayBuffer> = {
|
||||||
},
|
},
|
||||||
toASN: (value: ArrayBuffer) => {
|
toASN: (value: ArrayBuffer) => {
|
||||||
const bytes = new Uint8Array(value);
|
const bytes = new Uint8Array(value);
|
||||||
if (bytes[0] > 128) {
|
if (bytes[0] > 127) {
|
||||||
const newValue = new Uint8Array(bytes.length + 1);
|
const newValue = new Uint8Array(bytes.length + 1);
|
||||||
newValue.set(bytes, 1);
|
newValue.set(bytes, 1);
|
||||||
return new asn1.Integer({ valueHex: newValue });
|
return new asn1.Integer({ valueHex: newValue });
|
||||||
|
|
|
@ -62,10 +62,12 @@ export class EcCrypto {
|
||||||
const signature = signer.sign(options);
|
const signature = signer.sign(options);
|
||||||
const ecSignature = AsnParser.parse(signature, asn.EcDsaSignature);
|
const ecSignature = AsnParser.parse(signature, asn.EcDsaSignature);
|
||||||
|
|
||||||
return new Uint8Array(Buffer.concat([
|
const pointSize = this.getPointSize(key.algorithm.namedCurve);
|
||||||
Buffer.from(ecSignature.r),
|
const r = this.addPadding(pointSize, Buffer.from(ecSignature.r));
|
||||||
Buffer.from(ecSignature.s),
|
const s = this.addPadding(pointSize, Buffer.from(ecSignature.s));
|
||||||
])).buffer;
|
|
||||||
|
const signatureRaw = new Uint8Array(Buffer.concat([r, s])).buffer;
|
||||||
|
return signatureRaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async verify(algorithm: EcdsaParams, key: EcPublicKey, signature: Uint8Array, data: Uint8Array): Promise<boolean> {
|
public static async verify(algorithm: EcdsaParams, key: EcPublicKey, signature: Uint8Array, data: Uint8Array): Promise<boolean> {
|
||||||
|
@ -78,11 +80,12 @@ export class EcCrypto {
|
||||||
};
|
};
|
||||||
|
|
||||||
const ecSignature = new asn.EcDsaSignature();
|
const ecSignature = new asn.EcDsaSignature();
|
||||||
const size = signature.length / 2;
|
const pointSize = this.getPointSize(key.algorithm.namedCurve);
|
||||||
ecSignature.r = signature.buffer.slice(0, size);
|
ecSignature.r = this.removePadding(signature.slice(0, pointSize));
|
||||||
ecSignature.s = signature.buffer.slice(size, size + size);
|
ecSignature.s = this.removePadding(signature.slice(pointSize, pointSize + pointSize));
|
||||||
|
|
||||||
const ok = signer.verify(options, Buffer.from(AsnSerializer.serialize(ecSignature)));
|
const ecSignatureRaw = Buffer.from(AsnSerializer.serialize(ecSignature));
|
||||||
|
const ok = signer.verify(options, ecSignatureRaw);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,4 +195,34 @@ export class EcCrypto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static getPointSize(namedCurve: string) {
|
||||||
|
switch (namedCurve) {
|
||||||
|
case "P-256":
|
||||||
|
case "K-256":
|
||||||
|
return 32;
|
||||||
|
case "P-384":
|
||||||
|
return 48;
|
||||||
|
case "P-521":
|
||||||
|
return 66;
|
||||||
|
default:
|
||||||
|
throw new Error(`Cannot get size for the named curve '${namedCurve}'`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static addPadding(pointSize: number, bytes: Buffer) {
|
||||||
|
const res = Buffer.alloc(pointSize);
|
||||||
|
res.set(Buffer.from(bytes), pointSize - bytes.length);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static removePadding(bytes: Uint8Array) {
|
||||||
|
for (let i = 0; i < bytes.length; i++) {
|
||||||
|
if (!bytes[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return bytes.slice(i).buffer;
|
||||||
|
}
|
||||||
|
return new ArrayBuffer(0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue