NodeJS: не могу войти в узелJS 10.14.2 - PullRequest
0 голосов
/ 23 января 2019

Я прочитал следующее https://nodejs.org/api/crypto.html#crypto_class_sign и попытался скопировать код:

sign.js

const crypto = require('crypto');

const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1'
});

const sign = crypto.createSign('SHA256');
sign.write('some data to sign');
sign.end();
const signature = sign.sign(privateKey, 'hex');

const verify = crypto.createVerify('SHA256');
verify.write('some data to sign');
verify.end();
console.log(verify.verify(publicKey, signature));
// Prints: true or false

Но это выдает ошибку

>> node sign.js  
internal/crypto/keygen.js:73
    throw new ERR_INVALID_OPT_VALUE('publicKeyEncoding', publicKeyEncoding);
    ^

TypeError [ERR_INVALID_OPT_VALUE]: The value "undefined" is invalid for option "publicKeyEncoding"
    at parseKeyEncoding (internal/crypto/keygen.js:73:11)
    at check (internal/crypto/keygen.js:240:7)
    at Object.generateKeyPairSync (internal/crypto/keygen.js:53:16)
    at Object.<anonymous> (/Users/norfeldt/Desktop/AsymEnc/sign.js:3:42)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)

Обновление

Я сделал следующее изменение (как предложено @ottomeister)

const crypto = require('crypto')

const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1',
  publicKeyEncoding: { type: 'spki', format: 'der' },
  privateKeyEncoding: { type: 'pkcs8', format: 'der' },
})

const sign = crypto.createSign('SHA256')
sign.write('some data to sign')
sign.end()
const signature = sign.sign(privateKey, 'hex')

const verify = crypto.createVerify('SHA256')
verify.write('some data to sign')
verify.end()
console.log(verify.verify(publicKey, signature))
// Prints: true or false

Но теперь я получаю новую ошибку

internal/crypto/sig.js:80
  var ret = this._handle.sign(key, passphrase, rsaPadding, pssSaltLength);

Error: error:0906D06C:PEM routines:PEM_read_bio:no start line
    at Sign.sign (internal/crypto/sig.js:80:26)
    at Object.<anonymous> (/Users/norfeldt/Desktop/AsymEnc/sign.js:12:24)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:282:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3)

(я не знаю, что это меняет, но я хотел бы прочитать .pem файлы, которые я создаю с помощью openssl)

1 Ответ

0 голосов
/ 24 января 2019

Вы говорите, что используете Node.js версии 10, но ваша ссылка указывает на документацию для Node.js версии 11. Документация для версии 10: https://nodejs.org/dist/latest-v10.x/docs/api/crypto.html

В версии 11 *Свойства 1004 * и privateKeyEncoding объекта options, переданные в качестве второго аргумента crypto.generateKeyPairSync, являются необязательными.В версии 10 эти свойства не являются обязательными, они должны быть указаны .Ваша программа не предоставляет эти свойства, и поэтому она взрывается.

Если вы измените:

const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1'
});

на:

const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1',
  publicKeyEncoding:  { type: 'spki', format: 'der' },
  privateKeyEncoding: { type: 'pkcs8', format: 'der' }
});

, тогда ваша программа должнабыть намного счастливее.


Обновление

ОК, я установил Node 10 и запустил вашу программу.sign.sign() взрывается, потому что, как указано в документации, закрытый ключ должен быть в формате PEM.Он не может обработать закрытый ключ в формате DER, полученный моим первоначальным ответом.То же самое относится и к формату открытого ключа, переданного в verify.verify() - это должен быть PEM, а не DER.Поэтому измените это:

const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1',
  publicKeyEncoding:  { type: 'spki', format: 'der' },
  privateKeyEncoding: { type: 'pkcs8', format: 'der' }
});

на следующее:

const { privateKey, publicKey } = crypto.generateKeyPairSync('ec', {
  namedCurve: 'sect239k1',
  publicKeyEncoding:  { type: 'spki', format: 'pem' },
  privateKeyEncoding: { type: 'pkcs8', format: 'pem' }
});

То есть измените оба вхождения с 'der' на 'pem'.

Это позволит вашемуПрограмма запускается без исключения.Однако попытка проверки не удастся, и сообщенный результат, записанный последним вызовом console.log(), будет false.Это потому, что программа не сообщает verify.verify() кодировку, которая использовалась в строке privateKey.Чтобы исправить это и получить true результат проверки, измените:

verify.verify(publicKey, signature)

на:

verify.verify(publicKey, signature, 'hex')

, соответствующий строковой кодировке, которая была указана при создании подписи sign.sign().Документация не очень ясна в этой части, но из экспериментов видно, что если подпись является строкой, то вы всегда должны указывать кодировку строки.Единственное обстоятельство, при котором вы можете пропустить предоставление кодировки здесь, это если вы также пропустите ее при вызове sign.sign(), что привело бы к генерации signature как Buffer, а не как строка.

...