2009-05-19 19 views
24

So nach CodingHorror's fun with encryption und die thrashing Kommentare, wir überdenken, unsere eigene Verschlüsselung zu tun.Wie starte ich BouncyCastle?

In diesem Fall müssen wir einige Informationen weitergeben, die einen Benutzer an einen Drittanbieter-Dienst identifizieren, der dann einen Dienst auf unserer Website mit den Informationen plus einem Hash aufrufen wird.

Der zweite Dienst sucht nach Informationen zu diesem Benutzer und gibt ihn dann an den Drittanbieterdienst zurück.

Wir möchten diese Benutzerinformationen in den 3rd Party Service verschlüsseln und entschlüsseln, nachdem es herauskommt. Es ist also keine langlebige Verschlüsselung.

Zum Coding Horror Artikel, Coda Hale empfohlen BouncyCastle und eine hohe Abstraktion in der Bibliothek, um die Verschlüsselung für einen bestimmten Bedarf zu tun.

Mein Problem ist, dass die BouncyCastle Namespaces sind riesig und die Dokumentation ist nicht existent. Kann mir jemand auf diese Abstraktionsbibliothek auf hohem Niveau hinweisen? (Oder eine andere Option neben BouncyCastle?)

+5

Recon Ihre eigene Verschlüsselung lib zu schreiben? Gute Wahl! – Cheeso

+0

Obwohl es nicht viele Dokumente mit BouncyCastle gibt, finde ich ihre Mailingliste sehr hilfreich http://www.bouncycastle.org/csharpdevmailarchive/index.html. Sie können auch abonnieren, um Fragen zu stellen. Sie sollten auch die Quelle erhalten, es kommt mit Beispielen und Tests, die die meisten Anwendungsfälle abdecken. – Emmanuel

+0

Was Sie beschreiben, klingt wie ein typischer Anwendungsfall für OAuth - haben Sie darüber nachgedacht? –

Antwort

10

Abstraktion auf hohem Niveau? Ich nehme an, das höchste Niveau Abstraktionen in der Hüpfburg Bibliothek würden gehören:

Ich bin meist vertraut mit der Java-Version der Bibliothek. Vielleicht ist dieser Code-Schnipsel bieten Ihnen eine hoch genug Abstraktion für Ihre Zwecke (zB AES-256-Verschlüsselung verwendet):

public byte[] encryptAES256(byte[] input, byte[] key) throws InvalidCipherTextException { 
    assert key.length == 32; // 32 bytes == 256 bits 
    CipherParameters cipherParameters = new KeyParameter(key); 

    /* 
    * A full list of BlockCiphers can be found at http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/BlockCipher.html 
    */ 
    BlockCipher blockCipher = new AESEngine(); 

    /* 
    * Paddings available (http://www.bouncycastle.org/docs/docs1.6/org/bouncycastle/crypto/paddings/BlockCipherPadding.html): 
    * - ISO10126d2Padding 
    * - ISO7816d4Padding 
    * - PKCS7Padding 
    * - TBCPadding 
    * - X923Padding 
    * - ZeroBytePadding 
    */ 
    BlockCipherPadding blockCipherPadding = new ZeroBytePadding(); 

    BufferedBlockCipher bufferedBlockCipher = new PaddedBufferedBlockCipher(blockCipher, blockCipherPadding); 

    return encrypt(input, bufferedBlockCipher, cipherParameters); 
} 

public byte[] encrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException { 
    boolean forEncryption = true; 
    return process(input, bufferedBlockCipher, cipherParameters, forEncryption); 
} 

public byte[] decrypt(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters) throws InvalidCipherTextException { 
    boolean forEncryption = false; 
    return process(input, bufferedBlockCipher, cipherParameters, forEncryption); 
} 

public byte[] process(byte[] input, BufferedBlockCipher bufferedBlockCipher, CipherParameters cipherParameters, boolean forEncryption) throws InvalidCipherTextException { 
    bufferedBlockCipher.init(forEncryption, cipherParameters); 

    int inputOffset = 0; 
    int inputLength = input.length; 

    int maximumOutputLength = bufferedBlockCipher.getOutputSize(inputLength); 
    byte[] output = new byte[maximumOutputLength]; 
    int outputOffset = 0; 
    int outputLength = 0; 

    int bytesProcessed; 

    bytesProcessed = bufferedBlockCipher.processBytes(
      input, inputOffset, inputLength, 
      output, outputOffset 
     ); 
    outputOffset += bytesProcessed; 
    outputLength += bytesProcessed; 

    bytesProcessed = bufferedBlockCipher.doFinal(output, outputOffset); 
    outputOffset += bytesProcessed; 
    outputLength += bytesProcessed; 

    if (outputLength == output.length) { 
     return output; 
    } else { 
     byte[] truncatedOutput = new byte[outputLength]; 
     System.arraycopy(
       output, 0, 
       truncatedOutput, 0, 
       outputLength 
      ); 
     return truncatedOutput; 
    } 
} 

bearbeiten: Whoops, ich lese nur den Artikel, den Sie verknüpft. Es klingt, als würde er über Abstraktionen höherer Ebenen sprechen, als ich dachte (z. B. "eine vertrauliche Nachricht senden"). Ich fürchte, ich verstehe nicht ganz, worauf er hinauswächst.

+0

Vielen Dank für das Auschecken des Artikels ... es wäre schön, eine Bibliothek zu haben, wie das, was er beschreibt, da die Verwendungen für die Verschlüsselung viele sind und die Mißbräuche gleichmäßig sind größer. –

+0

+1 für die Mühe, aber nicht wirklich eine Antwort, die ich verwenden kann. –

+0

Adam Paynter schaut sich auch meine Frage an. Ich möchte einfach Text mit chcacha20 verschlüsseln. http://StackOverflow.com/Questions/38050559/illegalargumenttexception-chacha20-requires-128-bit-or-256-bit-key – Nepster

3

Angenommen, Sie schreiben Ihre Anwendung in Java, würde ich empfehlen, dass Sie keinen bestimmten Anbieter verwenden, sondern dass Sie Ihre Anwendung zusätzlich zu Sun JCE (Java Cryptography Extension) entwickeln. Dadurch können Sie unabhängig von den zugrunde liegenden Providern werden, dh Sie können Provider leicht wechseln, solange Sie weit verbreitete Algorithmen verwenden. Es gibt Ihnen ein gewisses Maß an Abstraktion, da Sie nicht alle Details der Implementierungen kennen müssen und Sie möglicherweise ein wenig davor schützen können, die falschen Klassen zu verwenden (z. B. rohe Verschlüsselung ohne richtige Padding usw.) eine anständige Menge an Dokumentation und Codebeispielen.

0

JCE wird nicht für mich arbeiten, weil wir 256 Bit Stärke wollen und die Java-Konfiguration auf dem System nicht ändern können, um es zu erlauben. Schade, das Bouncy Castle hat keine API so hoch wie JCE.

"Beachten Sie jedoch, dass Bouncycastle aus zwei Bibliotheken besteht, der Lightweight-Crypto-Bibliothek und der JCE-Provider-Interface-Bibliothek. Die Keysize-Einschränkungen werden von der JCE-Ebene erzwungen, Sie müssen diese Ebene jedoch nicht verwenden.Wenn Sie nur den leichten Crypto-API verwenden, um direkt haben Sie keine Einschränkungen, egal welche Richtliniendateien werden oder nicht installiert sind.“ http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography

+0

Ich würde lieber die 256-Bit-Anforderung als die Möglichkeit, eine High-Level-Schnittstelle und verwenden die Möglichkeit, Anbieter einfach zu wechseln. Ich bin kein Fan der Bouncycastle-Bibliothek, da sie zu viele Mängel für meinen Geschmack hat. Selbst wenn ich Bouncycastle während der Entwicklung verwenden würde, würde ich es gerne für etwas Besseres ändern wollen, sobald mein Code in Produktion geht. Vielseitigkeit ist ein wichtiger Aspekt beim Entwurf einer Krypto-Anwendung. Sich auf einen Anbieter oder eine Gruppe von Krypto-Primitiven zu beschränken, kann einen sehr verletzen. – Accipitridae

1

ich habe tatsächlich gefunden, dass diese Probe statt 256 Bit Standard-128-Bit-Verschlüsselung verwendet ich habe eine kleine Änderung vorgenommen:.

BlockCipher blockCipher = new AESEngine(); 

jetzt wird:

BlockCipher blockCipher = new RijndaelEngine(256); 

und es funktioniert zusammen mit meiner Client-Anwendung C++ AES256 Verschlüsselung

2

Ein Beispiel für einen hoch (ihn) -Level-API in BouncyCastle würde das CMS (Cryptographic Message Syntax) Paket sein. Diese wird in einem separaten Jar (bcmail) vom Provider selbst geliefert und in das JCE geschrieben (die C# -Version wird jedoch gegen die Lightweight-API geschrieben).

"Senden Sie eine vertrauliche Nachricht" wird grob gesagt von der CMSEnvelopedDataGenerator-Klasse implementiert, und alles, was Sie wirklich tun müssen, ist es die Nachricht zu geben, einen Verschlüsselungsalgorithmus (alle Details intern behandelt) auszuwählen und dann einen oder anzugeben Weitere Möglichkeiten, wie ein Empfänger die Nachricht lesen kann: Dies kann auf einem öffentlichen Schlüssel/Zertifikat, einem gemeinsamen Geheimnis, einem Passwort oder sogar einem Schlüsselvereinbarungsprotokoll basieren. Sie können mehr als einen Empfänger für eine Nachricht haben, und Sie können verschiedene Arten von Empfängern mischen und abgleichen.

Sie können CMSSignedDataGenerator verwenden, um ähnlich eine überprüfbare Nachricht zu senden. Wenn Sie signieren und verschlüsseln möchten, sind die CMS-Strukturen nestbar/zusammensetzbar (die Reihenfolge könnte jedoch wichtig sein). Es gibt auch CMSCompressedDataGenerator und kürzlich CMSAuthenticatedData.