2016-10-25 6 views
2

Ich arbeite mit der Bouncy Castle Library und finde keine Möglichkeit, eine unverschlüsselte Nachricht zu signieren, ohne sie zuvor zu hashen/aufzufüllen. Ich bin nicht sicher, welche Parameter als alg übergeben werden.Wie kann ich in Bouncy Castle eine rohe Nachricht signieren (ohne sie vorher zu hashen)?

Als ich einen Digest mit PKCS v1.5 Padding signierte, verwendete ich: "SHA1WithRSA", "SHA256WithRSA" usw. (Je nach Digest-Typ).

signature = Signature.getInstance(alg, JCEProvider.CRYPTO_PROVIDER_NAME); 
+1

Eine Signatur wird normalerweise definiert, indem der Hash einer Nachricht mit dem privaten Schlüssel des Benutzers verschlüsselt wird. Wenn Sie den Hash-Teil aus irgendeinem Grund nicht verwenden möchten, können Sie Ihren Standardverschlüsselungsalgorithmus verwenden, aber den privaten Schlüssel anstelle des öffentlichen Schlüssels übergeben. Bedenken Sie jedoch, dass dadurch die Vertraulichkeit oder Integrität einer Nachricht nicht erhalten bleibt. Diese Methode bietet nur Nichtabstreitbarkeit. – CoconutBandit

+0

Was Sie wollen, heißt Signatur mit Wiederherstellung. Siehe die [SignerWithRecovery] (https://www.bouncycastle.org/docs/docs1.5on/org/bouncycastle/crypto/SignerWithRecovery.html) Schnittstelle und implementierende Klassen. –

+1

Hinweis Hashing und Auffüllen sind getrennt, und RSASSA-PKCS1-v1_5 enthält ASN.1-Codierung mit AlgorithmIdentifier _plus_ Auffüllen mit 01 FF ... 00; siehe rfc3447. Zusätzlich zu der von @JamesKPolk vorgeschlagenen direct/'lightweight'-API können Sie Typ-01-Padding aber _not_ ASN.1-Encodierung über die Provider-Schnittstelle mit dem Algorithmus 'NoneWithRSA' oder einfach' RSA' erhalten. Bouncy Anbieter kann auch PSS mit verschiedenen Hashes, und ohne irgendwelche RSASSA-PSS RawRSASSA-PSS NoneWithRSASSA-PSS' –

Antwort

0

Raw Signing ist nichts anderes als modulare Potenzierung. Jetzt scheint es zwei Möglichkeiten zu geben, aber im Grunde wird nur eine übrig bleiben. Ich werde das unten erklären.

Zunächst würde man meinen, dass die Verwendung eines Signature mit "NoneWithRSA" funktionieren sollte. Der Algorithmus existiert zwar, aber leider puffert er immer noch; Es streift nur die ASN.1-Struktur ab, die die Hash-Funktion und den Wert angibt. Damit ist man nicht erreichbar.

Obwohl signing is not the same as encryption, beide Operationen am Ende auf modulare Exponentiation beruhen. So ist es zum Glück möglich, eine Cipher Instanz zu verwenden, um die Funktionalität zu erstellen benötigen Sie:

Security.addProvider(new BouncyCastleProvider()); 

Cipher rsa = Cipher.getInstance("RSA/ECB/NoPadding", BouncyCastleProvider.PROVIDER_NAME); 
rsa.init(Cipher.DECRYPT_MODE, kp.getPrivate()); 
byte[] signatureUsingCipher = rsa.doFinal("owlstead" 
     .getBytes(StandardCharsets.UTF_8)); 
System.out.println(Hex.toHexString(signatureUsingCipher)); 

Jetzt eine Sache, hier zu bemerken ist, dass Hüpfburg eine etwas andere Operation als die SunJCE Anbieter von Oracle durchführt. Anstatt nur die Auffüllung zu entfernen, vergißt es auch , um den Chiffretext durch den I2OSP Algorithmus zu setzen (sehen Sie den PKCS # 1 Standard), der richtig zur Ausgabegröße des Moduls kodiert. Sie können also einen kleineren Chiffretext als 128 Bytes für bestimmte Schlüssel/Klartext-Kombinationen haben. Dies ist sehr einfach zu sehen, indem der Wert 0 verschlüsselt wird, wobei die Ausgabe null Byte ist.

Abschließend beachten Sie, dass die Angabe Cipher.ENCRYPT Modus oder Cipher.DECRYPT Modus keinen Unterschied macht; beide führen einfach eine modulare Exponentiation durch. Cipher.DECRYPT erwartet jedoch eher einen privaten Schlüssel, weshalb ich ihn im obigen Code verwendet habe.

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
kpg.initialize(1024); 
KeyPair kp = kpg.generateKeyPair(); 
Verwandte Themen