Sign
и Verify
не только поддерживают PEM-формат, но также и DER-формат (оба описаны в ответ от Маартена Бодьюса). Кроме того, и Pkcs8- ( RFC 5208 и здесь ) и ключи Sec1-EC ( SECG SEC1, раздел C.4 и здесь ) может быть использован. Однако raw EC-ключи напрямую не поддерживаются. Поэтому, если ключи доступны только как необработанные ключи, преобразование всегда необходимо. Но это преобразование гораздо проще реализовать, чем в опубликованном коде, так что (на мой взгляд) не требуется значительных дополнительных усилий, например, для подписи:
var buf1 = Buffer.from('308141020100301306072a8648ce3d020106082a8648ce3d030107042730250201010420', 'hex'); // specific byte-sequence for curve prime256v1
var buf2 = Buffer.from('<Raw private key as hex string>', 'hex'); // raw private key (32 bytes)
var privateKeyPkcs8Der = Buffer.concat([buf1, buf2], buf1.length + buf2.length);
var sign = crypto.createSign('SHA384');
sign.write(<data to sign>);
sign.end();
var signature = sign.sign({ key: privateKeyPkcs8Der, format: 'der', type: 'pkcs8' }); // specify format and type
Используемый ключдля подписи privateKeyPkcs8Der
- это ключ Pkcs8 в формате DER ( без необработанного открытого ключа).
В отличие от опубликованного кода:
- вместо PEM-формата используется DER-формат.
- только необработанный закрытый ключ встраивается в контейнер Pkcs8, а не необработанный открытый ключ.
buf1
содержит последовательность байтов, принадлежащую простому256v1 (secp256r1) и Pkcs8-контейнер без необработанного открытого ключа. Примечание : Последовательность байтов немного отличается от последовательности байтов, используемой в размещенном коде. Это связано с тем, что последовательность байтов также содержит информацию о длине, и это зависит от того, встроен ли необработанный открытый ключ или нет.
То же самое относится к проверке:
var buf1 = Buffer.from('3059301306072a8648ce3d020106082a8648ce3d030107034200', 'hex'); // specific byte-sequence for curve prime256v1
var buf2 = Buffer.from('<Raw public key as hex string>', 'hex'); // raw public key (uncompressed, 65 bytes, startting with 04)
var publicKeyX509Der = Buffer.concat([buf1, buf2], buf1.length + buf2.length);
var verify = crypto.createVerify('SHA384');
verify.write(<data to sign>);
verify.end();
var verified = verify.verify({ key: publicKeyX509Der, format: 'der', type: 'spki' }, signature); // specify format and type
Ключ, используемый для проверки, publicKeyX509Der
, является ключом X.509-SubjectPublicKeyInfo-key (SECG SEC1, раздел C.3 ) в формате DER.
Как и в случае подписи:
- вместо формата PEM используется формат DER.
buf1
содержит последовательность байтов, принадлежащую prime256v1.
В опубликованном коде методы класса ECDH
используются для получения необработанного открытогоключ от необработанного закрытого ключа. Вместо этого метод createPublicKey
- и export
можно использовать для получения ключа X.509-SubjectPublicKeyInfo из ключа Pkcs8:
var publicKey = crypto.createPublicKey({ key: privKeyPkcs8DER, type: 'pkcs8', format: 'der' });
var publicKeyX509Der = publicKey.export({type: 'spki', format: 'der'})
Здесь privateKeyPkcs8Der
- это ключ Pkcs8 ( с или без необработанного открытого ключа), а publicKeyX509Der
- это ключ X.509-SubjectPublicKeyInfo, оба в DER-формат.
Примечание : Вместо Pkcs8-контейнера можно также использовать Sec1-контейнер. Однако тогда структура ключа и последовательности байтов должны быть соответствующим образом адаптированы. Использование Sec1-контейнера описано здесь , но для другой кривой (secp256 k 1), так что последовательности байтов не могут быть просто скопированы.