2009-05-19 26 views
24

Quindi, dopo il CodingHorror's fun with encryption e i commenti thrash, stiamo riconsiderando la nostra crittografia.Come iniziare a utilizzare BouncyCastle?

In questo caso, è necessario passare alcune informazioni che identificano un utente a un servizio di terze parti che quindi richiamerà un servizio sul nostro sito Web con le informazioni più un hash.

Il secondo servizio cerca informazioni su quell'utente e poi lo restituisce al servizio di terze parti.

Vogliamo crittografare queste informazioni utente che entrano nel servizio di terze parti e decrittografarlo dopo che è uscito. Quindi non è una crittografia longeva.

Nell'articolo horror di codifica, Coda Hale ha consigliato BouncyCastle e un'astrazione di alto livello nella libreria per eseguire la crittografia specifica per una particolare esigenza.

Il mio problema è che gli spazi dei nomi di BouncyCastle sono enormi e la documentazione è inesistente. Qualcuno può indicarmi questa libreria di astrazione di alto livello? (Oppure un'altra opzione oltre a BouncyCastle?)

+5

riconsiderando scrivere il proprio lib crittografia? Bella scelta! – Cheeso

+0

Anche se non c'è molta documentazione con BouncyCastle, trovo la loro mailing list molto utile http://www.bouncycastle.org/csharpdevmailarchive/index.html. Puoi anche iscriverti per fare domande. Si dovrebbe anche ottenere la fonte che viene fornito con esempi e test, che coprono la maggior parte dei casi d'uso. – Emmanuel

+0

Quello che stai descrivendo sembra un tipico caso d'uso per OAuth: hai pensato di usarlo? –

risposta

10

Astrazione di alto livello? Suppongo che le più alte astrazioni di livello nella libreria Bouncy Castle dovrebbe includere:

Sono principalmente familiare con la versione Java della libreria. Forse questo frammento di codice vi offrirà un'astrazione abbastanza alto per i vostri scopi (ad esempio utilizza la crittografia AES-256):

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; 
    } 
} 

Edit: Ops, ho appena letto l'articolo si è collegato al. Sembra che parli di astrazioni di livello ancora più elevato di quanto pensassi (ad esempio, "invia un messaggio confidenziale"). Temo di non capire bene a cosa stia andando.

+0

Grazie per aver controllato l'articolo ... sarebbe bello avere una libreria come quello che sta descrivendo come gli usi per la crittografia sono molti e gli abusi sono anche maggiore. –

+0

+1 per lo sforzo ma non è davvero una risposta che posso usare. –

+0

Adam Paynter dà anche un'occhiata alla mia domanda. Voglio semplicemente crittografare il testo usando chcacha20. http://stackoverflow.com/questions/38050559/illegalargumentexception-chacha20-requires-128-bit-or-256-bit-key – Nepster

3

Supponendo di scrivere l'applicazione in Java, si consiglia di non utilizzare un provider specifico, ma di sviluppare l'applicazione su JCE di Sun (Java Cryptography Extension). Ciò può renderti indipendente da qualsiasi fornitore sottostante, ad esempio, puoi cambiare facilmente i provider finché usi cifrari ampiamente implementati. Ti dà un certo livello di astrazione in quanto non devi conoscere tutti i dettagli delle implementazioni e potresti proteggerti un po 'dall'usare le classi sbagliate (ad es. Usando la crittografia grezza senza padding adeguato ecc.) Inoltre, Sun fornisce una discreta quantità di documentazione e esempi di codice.

0

JCE non funzionerà per me perché vogliamo una potenza di 256 bit e non possiamo modificare la configurazione java sul sistema per consentirglielo. Peccato che il castello gonfiabile non abbia un'API di alto livello come JCE.

"Nota che bouncycastle è costituito da due librerie, la libreria di crittografia leggera e la libreria di interfaccia del fornitore JCE.Le restrizioni di keysize vengono applicate dal livello JCE, ma non è necessario utilizzare questo livello.Se si utilizza l'API Crypto leggero direttamente non si dispone di alcuna restrizione, non importa quale file politica sono o non sono installati." http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography

+0

Preferisco abbandonare il requisito a 256-bit piuttosto che la possibilità di utilizzare un'interfaccia di alto livello e la possibilità di cambiare fornitore facilmente. Non sono un fan della biblioteca di bouncycastle, dal momento che ha troppi difetti per i miei gusti. Quindi, anche se usassi il bouncycastle durante lo sviluppo, vorrei essere in grado di passare a qualcosa di meglio una volta che il mio codice entra in produzione. La versatilità è un aspetto importante quando si progetta un'applicazione crittografica. Il blocco di un provider o di una serie di primitive crittografiche può farti molto male. – Accipitridae

1

realtà ho scoperto che questo campione utilizza la crittografia a 128 bit di default al posto di 256 bit ho fatto un piccolo cambiamento:.

BlockCipher blockCipher = new AESEngine(); 

diventa ora:

BlockCipher blockCipher = new RijndaelEngine(256); 

e funziona insieme con la mia applicazione client di crittografia AES a 256 C++

2

Un esempio di un alto (er) API-level in BouncyCastle sarebbe la (Cryptographic Message Syntax) pacchetto di CMS. Questo viene fornito in un vaso separato (bcmail) dal provider stesso, e viene scritto sul JCE (la versione C# è scritta rispetto all'API leggera).

"Invia un messaggio confidenziale" è implementato, in parole povere, dalla classe CMSEnvelopedDataGenerator e tutto ciò che è necessario fare è fornire il messaggio, scegliere un algoritmo di crittografia (tutti i dettagli gestiti internamente), quindi specificare uno o più modi in cui un destinatario sarà in grado di leggere il messaggio: questo può essere basato su una chiave pubblica/certificato, un segreto condiviso, una password o persino un protocollo di chiave d'accordo. Puoi avere più di un destinatario su un messaggio e puoi combinare tipi di destinatario.

È possibile utilizzare CMSSignedDataGenerator per inviare un messaggio verificabile allo stesso modo. Se si desidera firmare e crittografare, le strutture CMS sono nidificabili/componibili (ma l'ordine potrebbe essere importante). C'è anche CMSCompressedDataGenerator e recentemente aggiunto CMSAuthenticatedData.

1

È possibile utilizzare:

byte[] process(bool encrypt, byte[] input, byte[] key) 
{ 
    var cipher = CipherUtilities.GetCipher("Blowfish"); 
    cipher.Init(false, new KeyParameter(key)); 
    return cipher.DoFinal(input); 
} 

// Encrypt: 
byte[] encrypted = process(true, clear, key); 

// Decrypt: 
byte[] decrypted = process(false, encrypted, key); 

See: https://github.com/wernight/decrypt-toolbox/blob/master/dtDecrypt/Program.cs

Problemi correlati