2015-09-10 3 views
5

Wie angegeben here, ist die Länge der Nachrichtensignatur gleich dem Modul des privaten Schlüssels, aka der öffentliche Schlüssel.RSA Signature Size Mismatch

Ich implementiere ein System, das eine Nachricht signiert, und ich habe eine Größenabweichung, die ich nicht lösen kann. Ich verwende crypto++.

Hier ist der Code, die ich benutze:

/* Create RSA Keys */ 
RSA::PrivateKey privateKey; 
privateKey.GenerateRandomWithKeySize(prng, 3072); 
RSA::PublicKey publicKey(privateKey); 
cout << ">> RSA Keys generated"; 
    /* Key Size */ 
    string spki; 
    StringSink sSink(spki); 
    publicKey.Save(sSink); 
    cout <<" ("<< spki.size()<<" bytes)"<<endl; 

RSASSA_PKCS1v15_SHA_Signer signer(privateKey); 
size_t length = signer.MaxSignatureLength(); 
cout <<"MaxSignatureLength " <<length<<endl; 
    SecByteBlock signature(length); 

Und der Ausgang ist:

>> RSA Keys generated (420 bytes) 
>> ServerHello sent (436 bytes) 
    MaxSignatureLength 384 
    RSA Signature length 384 

Sollte nicht die MaxSignatureLength und die RSA Signature length 420 Bytes lang?

Ist das Problem mit dem Algorithmus, den ich verwende?

+0

Ich bin nicht allzu vertraut mit Krypto noch Programmierung mit Verschlüsselungsalgorithmen jedoch, wenn Ich habe einige Nachforschungen angestellt. Ich habe diese Website gefunden, die Ihnen vielleicht etwas Hilfe bietet. http://www.cryptop.com/docs/ref/index.html –

+0

@Eisen - Related, ich denke, Sie übergeben rohe Bytes zu 'Crafter', und das könnte Sie später in Schwierigkeiten bringen, wenn Sie eine Nachricht haben, die sich erstreckt mehrere On-the-Wire (oder Over-the-Air) Layer 1 Frames. Haben Sie [Protokollpuffer] (https://github.com/google/protobuf) angeschaut? Ich denke, du kannst sie benutzen, um eine Nachricht in 'Crafter' zu gestalten. Oder Sie können ASN.1 Ihre Nachrichten verschlüsseln. Oder Sie können etwas wie ['BSON'] (http://bsonspec.org/) verwenden. In diesen Fällen wissen Sie die Länge der Nachricht, die Sie gesendet und empfangen haben. – jww

Antwort

3

Sollte die MaxSignatureLength und die RSA Signature Länge nicht 420 Bytes lang sein?

Nein. Sie fragen nach einem Schlüssel mit 3072 Bits oder 384 Bytes. Das ist die Grenze für die Größe der Signatur.

Jedes Kryptosystem wird wahrscheinlich in diesem Bereich anders sein.

cout <<" ("<< spki.size()<<" bytes)"<<endl; 

Dies ist die Größe von {OID,n,e} mit dem ASN.1 Framing oder Overhead. Sehen Sie Ihre vorherige Frage Sending PublicKey within packet payload für wie es aussieht (insbesondere die Ausgabe des Befehls dumpasn1 rsa-public.der).

cout <<"MaxSignatureLength " <<length<<endl; 

Dies ist n - 1 für RSA, wenn ich mich richtig erinnere.

Ist das Problem mit dem Algorithmus, den ich verwende?

Nein, Sie tun Dinge richtig, indem Sie MaxSignatureLength() aufrufen.


>> RSA Keys generated (420 bytes) 
>> ServerHello sent (436 bytes) 

Ich spekulierte einfach, aber es scheint, dass Sie erscheinen Designprobleme zu haben, auch.

Wenn Sie eine Nachricht wie die ServerHello verschlüsseln, verschlüsseln Sie sie normalerweise unter einer symmetrischen Chiffre wie AES oder Camellia. Dann nehmen Sie diesen symmetrischen Verschlüsselungsschlüssel und verschlüsseln ihn unter dem RSA-Schlüssel. Schließlich senden Sie das Paar {encrypted symmetric cipher key, encrypted message under symmetric cipher} an die andere Partei.

In dem oben beschriebenen System verschlüsseln Sie nur 16 oder 32 Bytes unter dem öffentlichen Schlüssel.


ich denken, was Sie sollten ein integriertes Verschlüsselungsschema tun verschlüsselte Nachricht wird unter Verwendung hin und her zu senden. Siehe dazu Elliptic Curve Integrated Encryption Scheme (ECIES) und Discrete Logarithm Integrated Encryption Scheme (DLIES). ECIES arbeitet über elliptischen Kurven und DLIES über ganze Zahlen.

Integrierte Verschlüsselungsschemata haben einige sehr wünschenswerte Sicherheitseigenschaften, wie sie sind IND-CCA2. Sie erreichen es durch nicht ermöglicht Ihnen einige Dinge zu tun, wie die Wiederverwendung eines Sicherheitskontextes, so dass die Sicherheit in das Schema gebacken wird.

Sie müssen das Schlüsselverteilungsproblem jedoch noch lösen. Das ist ein heikles Problem, und wir haben keine gute, skalierbare Lösung.

Und jetzt sehen Sie, warum Algorithmus Agilität wichtig ist, und warum Sie wollen, dass OID als Teil des Schlüssels während der Handshake-Phase gesendet :)

+0

Danke für die mehr als vollständige Antwort! Aber warum heißt es, dass der Schlüssel 420 Byte lang ist? Liegt es daran, dass der 'RSA: PublicKey' mehr Daten (Header/Footer) als der * actual * Schlüssel enthält? Sie sagten auch, dass ich eine zu lange Nachricht habe. In der Tat ist die Nachricht der "Server Public ECDHE key", der 32 Bytes lang ist. Ist das zu lang? Oder meintest du 'ServerHello', wenn du eine Nachricht sagst? In diesem Fall ist es normal, ich lege den 'rng' (16 Bytes) vor den publicKey. Und 420 + 16 = 436 :) – EisenHeim

+1

@Eisen - Ich habe der Antwort einige weitere Informationen hinzugefügt. – jww