我想在我的Blackberry应用程序中使用BouncyCastle J2ME / RIM Crypto。
我遇到的问题是我想从将密钥发送到BlackBerry的C#.NET程序生成加密公钥。
是否可以使用原始字符串加密邮件?另外,我是否需要了解其他常见变量,例如modulo等?道歉,但我对密码算法完全不熟悉。
我是否需要BouncyCastle,或者可以使用RIM Crypto完成上述工作吗?
谢谢, 康纳
答案 0 :(得分:3)
我是使用bouncycastle做的,但RIM Crypto与之类似。 根据例子。如你所见,键是字符串......:
public CypherDecypherExample()
{
String plain ="a plain string";
String cipher = null;
String decipher = null;
byte [] byte_cipher = null;
byte [] byte_plain = null;
// key |-- 128 bit -->|-- 256 bit --->|
String key = "aaaaaaaaaaaaaaaacccccccccccccccc";
String iv = "bbbbbbbbbbbbbbbb";
System.out.println("bouncycastle.plain: " + plain);
try {
byte_cipher = encrypt(plain.getBytes(), key.getBytes(), iv.getBytes());
cipher = new String(byte_cipher);
System.out.println("bouncycastle.cipher: " + cipher);
} catch (Exception e) {
e.printStackTrace();
}
try {
byte_plain = decrypt(byte_cipher, key.getBytes(), iv.getBytes());
decipher = new String(byte_plain);
System.out.println("bouncycastle.decipher: " + decipher);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
throws Exception
{
String plain = new String(data);
System.out.println("bouncycastle.cipherData: " + plain);
int minSize = cipher.getOutputSize(data.length);
byte[] outBuf = new byte[minSize];
int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
int length2 = cipher.doFinal(outBuf, length1);
int actualLength = length1 + length2;
byte[] result = new byte[actualLength];
System.arraycopy(outBuf, 0, result, 0, result.length);
System.out.println("bouncycastle.cipherData returning");
return result;
}
private static byte[] decrypt(byte[] cipher, byte[] key, byte[] iv) throws Exception
{
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher((BlockCipher) new CBCBlockCipher(
new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.init(false, ivAndKey);
return cipherData(aes, cipher);
}
private static byte[] encrypt(byte[] plain, byte[] key, byte[] iv) throws Exception
{
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
new AESEngine()));
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key), iv);
aes.init(true, ivAndKey);
return cipherData(aes, plain);
}
答案 1 :(得分:3)
RSA公钥由两部分组成,而不仅仅是我想的一部分。
有Exponent
和Modulus
。这些都是数字,但我将它们作为Base64字符串从.NET客户端传递给Blackberry,并在被RIM Crypto函数使用时将它们解码为字节数组,因为它们将Byte数组作为参数。
byte[] exponent = Base64InputStream.decode("exponent base64 string");
byte[] modulus = Base64InputStream.decode("modulus base64 string");
NoCopyByteArrayOutputStream cipherUserData = new NoCopyByteArrayOutputStream();
RSACryptoSystem cryptoSystem = new RSACryptoSystem(1024);
// Create Public key using your variables from before
RSAPublicKey publicKey = new RSAPublicKey( cryptoSystem, exponent, modulus);
// Encryption engine objects
RSAEncryptorEngine eEngine = new RSAEncryptorEngine(publicKey);
PKCS1FormatterEngine fEngine = new PKCS1FormatterEngine(eEngine);
BlockEncryptor cryptoStream = new BlockEncryptor(fEngine, cipherUserData);
// Read the user data and encrypt while doing so. Remember, cryptoStream writes its data to
// cipherUserData so this is where the encrypted version of userData will end up.
cryptoStream.write( userData, 0, userData.length );
cryptoStream.close();
cipherUserData.close();
String encryptedUserData = new String(cipherUserData.toByteArray());
这几乎就是人们所有人,它很简单,但我花了很长时间才从API文档中获取这些内容:)
重要提示 RSA仅限于加密目的,因为您只能加密< =密钥大小的邮件。 对于1024位RSA,这是117字节,对于2048 RSA,则是245字节。要加密较大的消息,接受的方法是使用AES或类似方法加密消息,然后使用RSA公钥加密AES密钥。您将发送AES密文以及包含密钥的RSA密文以解密AES密文。
我上面写的内容花费了数天的修补和阅读。我希望它能帮助某人更快地实现目标。 :)