2014-11-20 6 views
1

Я играю с цифровыми сигнатурами с использованием node.js. Для целей тестирования я создал цифровую подпись некоторых XML-данных, сначала используя только SHA256, а затем используя RSA-SHA256.Разница между подписанием с SHA256 и подписанием с RSA-SHA256

Дело в том, что оба метода подписи создают точно такую ​​же подпись. Обе подписи идентичны. Если они идентичны, то почему два разных метода (SHA256 против RSA-SHA256)?

I включают в себя код ниже:

var crypto = require('crypto'), 
    path = require('path'), 
    fs  = require('fs'), 

    pkey_path = path.normalize('private_key.pem'), 
    pkey = ''; 

function testSignature(pkey) { 
    var sign1 = crypto.createSign('RSA-SHA256'), 
     sign2 = crypto.createSign('SHA256'); 

    fs.ReadStream('some_document.xml') 
     .on('data', function (d) { 
      sign1.update(d); 
      sign2.update(d); 
     }) 
     .on('end', function() { 
      var s1 = sign1.sign(pkey, "base64"), 
       s2 = sign2.sign(pkey, "base64"); 

      console.log(s1); 
      console.log(s2); 
     }); 
} 

// You need to read private key into a string and pass it to crypto module. 
// If the key is password protected, program execution will stop and 
// a prompt will appear in console, awaiting input of password. 

testSignature(fs.readFileSync(pkey_path)); 

Код выше выводит некоторую строку, которая является подпись, а затем снова точно та же самая строка, которая также подписи тех же данных, но создается с - предположительно - другой алгоритм, но он идентичен предыдущему ...

+0

Связанные Q & http://crypto.stackexchange.com/questions/11293/hmac-sha256-vs-rsa-sha256-which-one-to-use, если это какой-либо помощи. – jweyrich

+0

@jweyrich, к сожалению, это не связано. – Arim

ответ

11

Подпись не может быть создана только SHA256.

SHA256 - алгоритм хэширования; то есть алгоритм, создающий короткое число отпечатков пальцев, представляющее произвольный большой объем данных. Чтобы создать подпись, этот отпечаток по-прежнему должен быть обработан каким-то образом, чтобы разрешить идентификацию владельца отдельного ключа подписи. Одним из таких способов является шифрование отпечатка пальца с использованием закрытого ключа пары ключей rsa, позволяющего другим расшифровать результат с помощью связанного открытого ключа и, таким образом, проверить, что хранитель секретного ключа действительно должен был быть подписывающим.

В контексте вашего криптографического API, что схема шифрования RSA либо используется по умолчанию, когда лечение явно не указано, либо вид лечения выводится из секретного ключа, который вы используете в качестве параметра в вызове sign --- если это закрытый ключ RSA, он использует RSA; если это ключ DSA, он использует DSA; ...

3

Что вы ищете, это два раза подписи PKCS # 1 v1.5. Это детерминированная схема для подписей, поэтому она всегда возвращает тот же результат (сравните это с PSS-схемой, которая рандомизирована, обеспечивая лучшие свойства безопасности). Генерация подписи RSA PKCS # 1 v1.5 и генерация подписи PSS определена в пределах RFC 3447 (также известная как спецификации RSA v2.1).

Если вы используете код с RSA 512 бит (только для целей тестирования, использование ключа 2048 бита или более), то вы получите следующий результат:

Закрытого ключ:

-----BEGIN RSA PRIVATE KEY----- 
MIIBOgIBAAJBALLA/Zk6+4JFJ+XdU6wmUkuEhGa8hLZ+m6J3puZbc9E+DSt7pW09 
yMYwHF5MMICxE86cA6BrLjQLUUwvquNSK0ECAwEAAQJAcI/w4e3vdRABWNFvoCcd 
iWpwSZWK6LR/YuZ/1e1e2DJw+NXyPXbilSrLvAdxnjlWTsTxUiEy1jFh36pSuvMk 
AQIhAO4WtgysOoWkyvIOLIQwD0thWfdHxTpxqfd6flrBJ91hAiEAwDOQqHhnSeET 
+N/hwUJQtCkHBJqvMF/kAi4Ry5G+OeECIEg1Exlc0pLdm781lUKx4LGX4NUiKyrC 
di3cNJ4JnrGBAiEAi2gbYYbLbDO8F8TTayidfr9PXtCPhyfWKpqdv6i7cCECIH7A 
6bh0tDCl6dOXQwbhgqF4hXiMsqe6DaHqIw8+XLnG 
-----END RSA PRIVATE KEY----- 

подписи как основание 64 (с помощью кода):

YY6sur9gkHXH23cUbDMYjCJYqDdBK8GKp4XyRNl8H09cW8H/gKQI9Z6dkLMhNh7oPq1yABCRfTP8yRtfLVj7FA== 

и в шестнадцатиричном

618eacbabf609075c7db77146c33188c2258a837412bc18aa785f244d97c1f4f5c5bc1ff80a408f59e9d90b321361ee83ead720010917d33fcc91b5f2d58fb14 

расшифровывается с использованием RAW RSA (т. просто модульное возведение в степень с показателем общественного):

0001ffffffffffffffffffff003031300d0609608648016503040201050004202af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64 

Это очень яркий пример PKCS # 1 подпись, легко узнаваемым FF прокладкой, с последующим ASN.1 структура (начиная с 30, ПОСЛЕДОВАТЕЛЬНОСТЬ):

SEQUENCE (2 elem) 
    SEQUENCE (2 elem) 
    OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 {joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) nistAlgorithm(4) hashAlgs(2) sha256(1)} 
    NULL 
    OCTET STRING(32 byte) 2AF565B95E5F4479492C520C430F07AE05D2BCFF8923322E6F2EF6404D72AC64 

Так что дело в конце концов, это хеш, в этом случае за просто Test 123\n, как я не хотел, чтобы напечатать любой XML сегодня.

$ sha256sum some_document.xml 
2af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64 some_document.xml 

$ sha256sum some_document.xml 
2af565b95e5f4479492c520c430f07ae05d2bcff8923322e6f2ef6404d72ac64 some_document.xml 
+0

Thanx так много для этих имен! Я искал имена для этих двух разных форматов подписи SHA256WithRSA (2048) на века! Таким образом, детерминированный формат называется «PKCS # 1 v1.5», и это * DEFAULT * в JAVA. Второй вариант называется «PSS». Наконец, я понял! –

Смежные вопросы