由於某些原因,我需要使用塊大小爲256位的Rijndael de/compression,而不是使用128位塊大小的AES(原因是:數據使用Rijndael在PHP中進行了加密...)。如何使用Rijndael進行加密或解密以及256位的塊大小?
如何更改密碼的塊大小?
如果我剛剛得到一個"RIJNDAEL/CFB/PKCS5Padding"
的密碼,並試圖用256位初始化一個IV,我得到一個異常,因爲塊大小隻有128位。
由於某些原因,我需要使用塊大小爲256位的Rijndael de/compression,而不是使用128位塊大小的AES(原因是:數據使用Rijndael在PHP中進行了加密...)。如何使用Rijndael進行加密或解密以及256位的塊大小?
如何更改密碼的塊大小?
如果我剛剛得到一個"RIJNDAEL/CFB/PKCS5Padding"
的密碼,並試圖用256位初始化一個IV,我得到一個異常,因爲塊大小隻有128位。
任何Sun JCE提供程序都不支持除128位塊大小的Rijndael以外的其他任何提供程序:這是AES算法。要獲得256位塊大小的rijndael,你將不得不去其他地方。我建議Bouncycastle java庫。 RijndaelEngine類有一個構造函數,它接受以位爲單位的塊大小。大多數人發現PaddedBufferedBlockCipher類與適當的填充物一起使用會更方便,例如,
PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new RijndaelEngine(256), new PKCS7Padding());
需要注意的是PHP的mcrypt使用零字節填充所以new ZeroBytePadding()
應該用來代替new PKCS7Padding()
。
波紋管完全實現使用CBC
和RIJNDAEL 256
。
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.RijndaelEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.ZeroBytePadding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Base64;
public static String encryptWithAesCBC(String plaintext, String key, String iv)
{
try {
PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes());
cipher.init(true, ivAndKey);
return new String(Base64.encode(cipherData(cipher, plaintext.getBytes())));
} catch (InvalidCipherTextException e) {
throw new RuntimeException(e);
}
}
public static String decryptWithAesCBC(String encrypted, String key, String iv)
{
try {
byte[] ciphertext = Base64.decode(encrypted);
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());
CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes());
aes.init(false, ivAndKey);
return new String(cipherData(aes, ciphertext));
} catch (InvalidCipherTextException e) {
throw new RuntimeException(e);
}
}
private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data) throws InvalidCipherTextException
{
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[] cipherArray = new byte[actualLength];
for (int x = 0; x < actualLength; x++) {
cipherArray[x] = outBuf[x];
}
return cipherArray;
}
private String md5(String string)
{
try {
java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
byte[] array = md.digest(string.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < array.length; ++i) {
sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString();
} catch (java.security.NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
當使用CFB,PaddedBufferedBlockCipher
應該是替換以下:
PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CFBBlockCipher(new RijndaelEngine(256),8), new ZeroBytePadding());
// PHP mcrypt uses a blocksize of 8 bit for CFB
用法:
String salt = "fbhweui3497";
String key = md5(salt);
String iv = md5(md5(salt));
String encrypted = encryptWithAesCBC("text to encript", key, iv);
String decrypted = decryptWithAesCBC(encrypted, key, iv);
你能提供md5()嗎? String md5(String input){ \t \t String result = input; \t \t MessageDigest md; \t \t嘗試{ \t \t \t md = MessageDigest.getInstance(「MD5」); \t \t \t md.update(input.getBytes()); \t \t \t BigInteger hash = new BigInteger(1,md.digest()); \t \t \t result = hash.toString(16); \t \t \t while(result。長度()<32){// 40對於SHA-1 \t \t \t \t result =「0」+ result; \t \t \t} \t \t}趕上(拋出:NoSuchAlgorithmException E){ \t \t \t e.printStackTrace(); \t \t} \t \t返回結果; \t} 上述方法給出「java.lang.IllegalArgumentException:密鑰長度不是128/160/192/224/256位」。 – Krish
@Krish我剛剛添加到答案md5實現。 –
你可能必須確定您已經安裝了Java JCE無限制的加密類。它們不是典型的標準Java發行版的一部分,因爲它們在某些國家是非法的。 – Romain
已經有了它們。仍然無法找到如何獲得所需的塊大小的密碼對象 – Laures
然後我相信@GregS有答案。我曾相信Rijndael-256是JCE Unlimited Providers的一部分,但我習慣於使用我公司的定製化Java - 它有一個JCE提供商,但它可能是私有實現。 – Romain