因此,在CodingHorror's fun with encryption和抨击评论之后,我们正在重新考虑进行自己的加密。
在这种情况下,我们需要将识别用户的一些信息传递给第三方服务,然后第三方服务将使用信息和散列回调到我们网站上的服务。
第二项服务查找该用户的信息,然后将其传递回第三方服务。
我们想要加密进入第三方服务的这些用户信息,并在它出来后解密。所以这不是一个长期存在的加密。
在编码恐怖文章中,Coda Hale建议使用BouncyCastle和库中的高级抽象来进行特定需求的加密。
我的问题是BouncyCastle命名空间很大,而且文档不存在。谁能指点我这个高级抽象库? (或者除了BouncyCastle之外还有其他选择吗?)
答案 0 :(得分:12)
高级抽象?我想Bouncy Castle图书馆中最高级别的抽象包括:
我最熟悉Java的Java版本。也许这段代码片段会为您提供足够高的抽象(例如使用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;
}
}
编辑:哎呀,我刚看了你链接的文章。听起来他说的是比我想象的更高级别的抽象(例如,“发送机密信息”)。我担心我不太了解他的目标。
答案 1 :(得分:3)
假设您使用Java编写应用程序,我建议您不要使用特定的提供程序,而是在Sun的JCE(Java Cryptography Extension)之上开发应用程序。这样做可以使您独立于任何底层提供程序,即,只要您使用广泛实现的密码,就可以轻松切换提供程序。它确实为您提供了一定程度的抽象,因为您不必了解实现的所有细节,并且可以保护您使用错误的类(例如使用原始加密而没有适当的填充等)。此外,Sun提供大量的文档和代码示例。
答案 2 :(得分:2)
BouncyCastle中高(呃)级API的一个例子是CMS(Cryptographic Message Syntax)包。它从提供程序本身发送到一个单独的jar(bcmail)中,并写入JCE(但是C#版本是针对轻量级API编写的)。
“发送机密消息”大致由CMSEnvelopedDataGenerator类实现,您真正需要做的就是给它消息,选择加密算法(内部处理所有细节),然后指定一个或多个收件人能够阅读邮件的方式:这可以基于公钥/证书,共享密钥,密码甚至密钥协议协议。您可以在邮件上拥有多个收件人,并且可以混合和匹配收件人类型。
您可以使用CMSSignedDataGenerator类似地发送可验证的消息。如果要签名和加密,CMS结构是可嵌套/可组合的(但顺序可能很重要)。还有CMSCompressedDataGenerator,最近添加了CMSAuthenticatedData。
答案 3 :(得分:1)
我实际上发现此示例使用默认的128位加密而不是256位。我做了一点改变:
BlockCipher blockCipher = new AESEngine();
现在变为:
BlockCipher blockCipher = new RijndaelEngine(256);
它与我的客户端应用程序C ++ AES256加密一起使用
答案 4 :(得分:1)
您可以使用:
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);
请参阅:https://github.com/wernight/decrypt-toolbox/blob/master/dtDecrypt/Program.cs
答案 5 :(得分:0)
JCE对我不起作用,因为我们需要256位强度,并且无法更改系统上的java配置以允许它。太糟糕了,Bouncy Castle没有像JCE那样高级的API。
“但请注意,bouncycastle包含两个库,轻量级加密库和JCE提供程序接口库。密钥大小限制由JCE层强制执行,但您不需要使用此层。如果您只是使用轻量级加密API直接你没有任何限制,无论安装或未安装什么策略文件。“ http://www.coderanch.com/t/420255/Security/AES-cryptoPerms-Unlimited-Cryptography
答案 6 :(得分:0)
本书Beginning Cryptography with Java包含非常有用的示例和基于bouncycastle库的解释