Comment commencer à utiliser BouncyCastle? [fermé]
Donc après Codinghorr's fun with encryption et les commentaires cinglants, nous sommes en train de reconsidérer la possibilité de faire notre propre chiffrement.
dans ce cas, nous devons transmettre certaines informations qui identifient un utilisateur à un service tiers qui rappellera ensuite à un service sur notre site Web avec l'information plus un hachage.
le second service Recherche des informations sur cet utilisateur et les transmet ensuite au troisième service.
nous voulons crypter ceci l'information de l'Utilisateur entrant dans le service de tiers et le déchiffrer après qu'il sort. Ce n'est donc pas un cryptage de longue durée.
sur l'article coding horror, Coda Hale recommande BouncyCastle et une abstraction de haut niveau dans la bibliothèque pour faire le cryptage spécifique à un besoin particulier.
mon problème est que les espaces de noms de BouncyCastle sont énormes et que la documentation n'existe pas. Est-ce que quelqu'un peut m'indiquer cette bibliothèque d'abstraction de haut niveau? (Ou une autre option en outre BouncyCastle?)
7 réponses
abstraction de haut niveau? Je suppose que les abstractions de plus haut niveau dans la Bibliothèque du château gonflable incluraient:
- BlockCipher interface (chiffrement symétrique)
- BufferedBlockCipher classe
- AsymmetricBlockCipher interface
- BufferedAsymmetricBlockCipher classe
- CipherParameters interface (pour initialiser le algorithmes de chiffrement par bloc et asymétrique algorithmes de chiffrement par bloc)
je suis surtout familier avec la version Java de la bibliothèque. Peut-être que cet extrait de code vous offrira une abstraction assez élevée pour vos besoins (exemple: utiliser le cryptage 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;
}
}
Modifier: Oups, je viens de lire l'article que vous avez lié. On dirait qu'il parle d'abstractions de niveau encore plus élevé que ce que je pensais (par exemple, "envoyer un message confidentiel"). J'ai peur de ne pas assez comprendre ce qu'il devient.
en supposant que vous écrivez votre application en Java, je vous recommande de ne pas utiliser de fournisseur spécifique, mais de développer votre application en plus du JCE de Sun (Java Cryptography Extension). Cela peut vous rendre indépendant de tout fournisseur sous-jacent, C'est-à-dire, vous pouvez changer de fournisseur facilement aussi longtemps que vous utilisez des chiffreurs qui sont largement mis en œuvre. Il ne vous donne un certain niveau d'abstraction que vous ne devez pas connaître tous les détails des implémentations et peut vous protéger un peu à partir de l'utilisation des mauvaises classes (par exemple, en utilisant le cryptage brut sans rembourrage approprié etc) de plus, Sun fournit une quantité décente de documentation et des échantillons de code.
Un exemple de(re)-niveau de l'API dans BouncyCastle serait le CMS ( Syntaxe De Message Cryptographique). Cette version est envoyée dans un jar séparé (bcmail) du fournisseur lui-même, et est écrite pour le JCE (La version C# est cependant écrite contre L'API légère).
"envoyer un message confidentiel" est implémenté, en gros, par la classe Cmsen Developeddatagenerator, et tout ce que vous avez vraiment besoin de faire est de lui donner le message, choisir un algorithme de cryptage (tous les détails sont traités à l'interne), puis spécifiez une ou plusieurs façons dont un destinataire sera capable de lire le message: cela peut être basé sur une clé publique/un certificat, un secret partagé, un mot de passe, ou même un protocole d'accord de clé. Vous pouvez avoir plus d'un bénéficiaire sur un message, et vous pouvez mélanger et assortir les types de bénéficiaires.
vous pouvez utiliser CMSSignedDataGenerator pour envoyer un message vérifiable de la même manière. Si vous voulez signer et chiffrer, les structures CMS sont nestable / composable (mais l'ordre peut être important). Il y a aussi le Datatagenerator Cmscompressé et récemment ajouté des données Cmsauthenticated.
j'ai en fait trouvé que cet échantillon utilise le cryptage 128 bits au lieu de 256 bits. J'ai fait un peu de changement:
BlockCipher blockCipher = new AESEngine();
devient:
BlockCipher blockCipher = new RijndaelEngine(256);
et il fonctionne avec mon application client c++ cryptage AES256
Vous pouvez utiliser:
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);
voir:https://github.com/wernight/decrypt-toolbox/blob/master/dtDecrypt/Program.cs
JCE ne fonctionnera pas pour moi car nous voulons une force de 256 bits et ne pouvons pas modifier la configuration java du système pour l'autoriser. Dommage que le château gonflable n'ait pas D'API aussi haut-niveau que JCE.
" notez cependant que bouncycastle se compose de deux bibliothèques, la bibliothèque légère crypto et la bibliothèque d'interface JcE provider. Les restrictions keysize sont appliquées par la couche JCE, mais vous n'avez pas besoin d'utiliser cette couche. Si vous utilisez juste l'API de crypto légère directement vous ne pas avoir de restrictions, peu importe ce que les fichiers de politique sont ou ne sont pas installés." http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography
Le livre début de la cryptographie avec Java contient des exemples et des explications très utiles basés sur la bibliothèque bouncycastle