2009-08-10 6 views
1

Ich versuche eine Nachricht beliebiger Länge asynmetrisch mit Bouncycastle zu verschlüsseln. (1.4+ mit C#)Bouncycastle: was macht der subKeyID-Parameter von AddKeyTransRecipient?

Dies ist der Code, den ich gerade habe. Es soll (aber nicht) eine CMS-Nachricht erzeugen, bei der die Daten selbst mit AES256 mit einem zufälligen Schlüssel verschlüsselt sind und der Schlüssel mit dem öffentlichen Schlüssel von keyPair verschlüsselt ist.

keyPair ist ein RSA-Key (RsaKeyParameters)

public static byte[] Encrypt(byte[] input, AsymmetricCipherKeyPair keyPair) 
{ 
    CmsEnvelopedDataGenerator generator = new CmsEnvelopedDataGenerator(); 

    // those two lines are certainly wrong. 
    // I have no idea what the subKeyID parameter does 
    byte[] subKeyId = new byte[] {}; 
    generator.AddKeyTransRecipient(keyPair.Public, subKeyId); 

    CmsProcessableByteArray cmsByteArray = new CmsProcessableByteArray(input); 
    CmsEnvelopedData envelopeData = 
     generator.Generate(cmsByteArray, CmsEnvelopedDataGenerator.Aes256Cbc); 

    return envelopeData.GetEncoded(); 
} 

Was für die subKeyId Parameter in der Encrypt Methode ist und welchen Wert hat es haben müssen?

Antwort

0

Sehen Sie sich die Funktion TryKekAlgorithm in der EnvelopedDataTest.cs-Datei der BouncyCastle-Quelle an. Anstatt AddKeyTransRecipient auszuführen, führen sie AddKekRecipient aus.

public static byte[] Encrypt(byte[] input, AsymmetricCipherKeyPair keyPair) 
    { 
     CmsEnvelopedDataGenerator generator = new CmsEnvelopedDataGenerator(); 
     DerObjectIdentifier algOid = //initialize 

     //Still trying to figure out kekId here. 
     byte[] kekId = new byte[] { 1, 2, 3, 4, 5 }; 
     string keyAlgorithm = ParameterUtilities.GetCanonicalAlgorithmName("AES256"); 

     generator.AddKekRecipient(keyAlgorithm, keyPair.Public, kekId); 

     CmsProcessableByteArray cmsByteArray = new CmsProcessableByteArray(input); 
     CmsEnvelopedData envelopeData = 
      generator.Generate(cmsByteArray, CmsEnvelopedDataGenerator.Aes256Cbc); 

     return envelopeData.GetEncoded(); 
    } 

Edit: Ich denke, die kekId ist nur eine eindeutige Kennung verwendet, um den Schlüssel zu verweisen. Nur eine Möglichkeit, den Schlüssel zu "benennen". So können Sie ein Buch mit Schlüsseln haben, und jedes hat eine Kennung. Wenn Sie eine verschlüsselte Nachricht senden, teilt Ihnen die unverschlüsselte Schlüsselkennung mit, welcher der Schlüssel zum Verschlüsseln der Nachricht verwendet wurde.

Hier ist eine ziemlich gute Erklärung von Schlüsselkennungen auf Seite 140: [http://books.google.com/books?id=Pgg-Es2j3UEC&pg=PA140&lpg=PA140&dq=understanding+key+identifiers+encrypt&source=bl&ots=nFg0BzM2ht&sig=Ux5sreXMKyuEEZu0uaxE7cXC1VI&hl=en&ei=JKKJStbHGJivtgffsNznDA&sa=X&oi=book_result&ct=result&resnum=6#v=onepage&q=&f=false][1]

Und hier ist ein weiteres Buch, das BouncyCastleCrypto verwendet, aber es sieht aus wie sie wenig mehr taten als die Unit-Test-Quellcode Abzocke . Sie haben es ein wenig erklärt: [http://books.google.com/books?id=WLLAD2FKH3IC&pg=PA343&lpg=PA343&dq=CmsEnvelopedDataGenerator+AddKekRecipient&source=bl&ots=O9HinJm3yB&sig=K5Z99DIVWW4-0abPIFR7x4lzBhU&hl=en&ei=g6aJSrjeDuHktgennNjnDA&sa=X&oi=book_result&ct=result&resnum=6#v=onepage&q=CmsEnvelopedDataGenerator%20AddKekRecipient&f=false][2]

0

Um AES zu verwenden, ist es nicht ausreichend, einen AsymmetricCipherKeyPair zu verwenden.

Sie sollten ein X509-Zertifikat verwenden, bei dem der öffentliche Schlüssel von einer Zertifizierungsstelle (CA) signiert ist.

die subKeyId ist ein Attribut des Zertifikats, das Thema Key Identifier:

 (X509Certificate) cert.getSubjectUniqueID() 

Um eine Nachricht von artrary Länge zu verschlüsseln, sollten Sie AES verwenden nur eine symmetrische Keypassword auszutauschen und diesen Schlüssel für die symmetrische Verschlüsselung verwenden .

+0

Ich habe nur ein RSA-Schlüsselpaar. Daher kann ich getSubjectUniqueID() nicht verwenden, da kein Zertifikat vorhanden ist. – levinalex

+0

Betreff: "Um eine Nachricht mit arrarischer Länge zu verschlüsseln, sollten Sie AES nur zum Austausch eines symmetrischen Schlüsselpassworts verwenden und diesen Schlüssel für die symmetrische Verschlüsselung verwenden." (Ich denke du meinst RSA, AES ist ein symmetrischer Algorithmus) Ist das nicht genau das, was CMSEnvelopedData tun soll? – levinalex

2

aaronls ist ein wenig unfair an den Autor des Seins „Beginning Kryptografie mit Java“, die schließlich die ganze Einheit schrieb testet sich in erster Linie ...

Wie andere Kommentatoren darauf hingewiesen haben, arbeitet CMS mit Zertifikaten, Sie können nicht einfach einen öffentlichen Schlüssel übergeben; Der Schlüssel muss entweder über "SubjectKeyIdentifier" oder über "IssuerAndSerialNumber" referenziert werden können. Die zwei Alternativen von AddKeyTransRecipient erlauben dies. Wenn Ihnen diese Begriffe nichts bedeuten, müssen Sie wahrscheinlich Hintergrundinformationen zu X.509 lesen.

+0

Hah, das ist lustig. Ei auf meinem Gesicht, denke ich. – AaronLS