我正试图用两个不同的服务提供商解密加密的数据。
我使用的加密算法是:AES/CTR/PKCS5PADDING (带有PKCS5Padding的AES计数器模式)
在从另一端进行加密时,他们使用SunJCE作为服务提供者。
我正在尝试使用Bouncy城堡作为Java的提供者来解密加密的数据(来自python)。
我使用了同样的密钥和IV,这是用来加密的。
从我这边(解密时)和另一边(加密时)都有限制。我们都不能改变服务提供商.
Java的默认提供程序是SunJCE,因为我使用的是自定义的JVM版本,它不包含SunJCE库。如果我将SunJCE配置为提供程序(在不同的机器上尝试使用完整版本的Java ),我就能够成功地解密相同的加密数据。所以我觉得,这个代码没有其他问题。
请任何人帮助解密SunJCE的加密数据使用Bouncy城堡提供商。
下面是我使用的代码片段。
java.security.Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
IvParameterSpec iv = new IvParameterSpec(initVector);
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5PADDING", "BC");
// I tried with below line as well. No luck
//Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5PADDING", new org.bouncycastle.jce.provider.BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] textToDecryptInByte = Base64.toBytes(encrypted);
byte[] decrypted = cipher.doFinal(textToDecryptInByte);
return new String(decrypted);initVector和key是byte[]类型。
我解密时得到的异常:
org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher$BufferedGenericBlockCipher.doFinal (未知源,bco=19)在org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal (未知源,bco=43)的javax.crypto.Cipher.doFinal (未知源,bco=48)处损坏的pad块
发布于 2019-11-18 23:20:42
多年来,JCE中存在一个问题,即模式CTR中的AES正在使用NOPADDING,而不管您作为参数提供了什么。您可以找到一个日期为2007年的旧线程,其中描述了问题,并给出了两种解决方案--通常使用NOPADDING (最佳选择),或者在加密端添加自己的填充,并在解密侧将其剥离。
下面是到线程的链接(参见2007年11月25日大卫·胡克-4日的答案;凌晨1点06分):http://bouncy-castle.1462172.n4.nabble.com/SunJCE-versus-BouncyCastle-using-AES-CTR-PKCS5Padding-td1465907.html --这就是答案:你应该使用NoPadding,除非你真的想要填充物--就像Peter指出的那样,它是完全不必要的,而NoPadding是Sun正在生产的东西,不管您请求的是什么__。
这里是一个完整的示例程序,它演示了“错误”填充加密方面,我在JCE中使用PKCS5Padding,而在BC中对解密部分使用NOPADDING。通过将AesCtrNoPaddingDecryptBC更改为AesCtrNoPaddingDecrypt,可以将解密更改为JCE。
/*
* Herkunft/Origin: http://javacrypto.bplaced.net/
* Programmierer/Programmer: Michael Fehr
* Copyright/Copyright: frei verwendbares Programm (Public Domain)
* Copyright: This is free and unencumbered software released into the public domain.
* Lizenttext/Licence: <http://unlicense.org>
* getestet mit/tested with: Java Runtime Environment 8 Update 191 x64
* Datum/Date (dd.mm.jjjj): 19.11.2019
* Funktion: verschlüsselt einen string im aes ctr modus pkcs5padding mit jce
* entschlüsselt einen string im aes ctr modus nopadding mit bc
* Function: encrypts a string using aes ctr modus with pkcs5padding using JCE
* decrypts a string using aes ctr modus nopadding using BC
*
* Hinweis: die JCE arbeitet immer im NOPADDING-Modus, egal was alternativ angegeben ist !
* Notice: JCE works always in NOPADDING mode and not in PKCS5PADDING even if named !
* Link: http://bouncy-castle.1462172.n4.nabble.com/SunJCE-versus-BouncyCastle-using-AES-CTR-PKCS5Padding-td1465907.html
*
* Sicherheitshinweis/Security notice
* Die Programmroutinen dienen nur der Darstellung und haben keinen Anspruch auf eine
* korrekte Funktion, insbesondere mit Blick auf die Sicherheit !
* Prüfen Sie die Sicherheit bevor das Programm in der echten Welt eingesetzt wird.
* The program routines just show the function but please be aware of the security part -
* check yourself before using in the real world !
*/
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class AesCtrNoPaddingRandomString {
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException,
InvalidAlgorithmParameterException, NoSuchProviderException {
System.out.println("AES mode CTR PKCS5PADDING or NOPADDING ?");
Security.addProvider(new BouncyCastleProvider());
String plaintextString = "HelloWorld12345"; // hier 15 zeichen
String decryptedtextString = ""; // enthält später den entschlüsselten text
final byte[] keyByte = "12345678901234567890123456789012".getBytes("UTF-8"); // 32 byte
// random iv, 16 bytes long
final byte[] initvectorByte = new byte[16];
SecureRandom secureRandom = new SecureRandom();
secureRandom.nextBytes(initvectorByte);
byte[] plaintextByte = plaintextString.getBytes("UTF-8");
byte[] ciphertextByte = null;
byte[] decryptedtextByte = null;
// encryption
ciphertextByte = AesCtrPkcs5PaddingEncrypt(plaintextByte, keyByte, initvectorByte);
// decryption with bouncy castle
decryptedtextByte = AesCtrNoPaddingDecryptBC(ciphertextByte, keyByte, initvectorByte);
// decrypted text
decryptedtextString = new String(decryptedtextByte, "UTF-8");
// output
System.out.println("");
System.out.println("keyByte (hex) :" + printHexBinary(keyByte));
System.out.println("initvectorByte (hex) :" + printHexBinary(initvectorByte));
System.out.println("plaintextString :" + plaintextString);
System.out.println("plaintextByte (hex) :" + printHexBinary(plaintextByte));
System.out.println("= = = Encryption AES/CTR/PKCS5PADDING JCE = = =");
System.out.println("ciphertextByte (hex) :" + printHexBinary(ciphertextByte));
System.out.println("= = = Decryption AES/CTR/NOPADDING BC = = =");
System.out.println("decryptedtextByte (hex):" + printHexBinary(decryptedtextByte));
System.out.println("decryptedtextString :" + decryptedtextString);
}
public static byte[] AesCtrPkcs5PaddingEncrypt(byte[] plaintextByte, byte[] keyByte, byte[] initvectorByte)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
byte[] ciphertextByte = null;
SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
IvParameterSpec ivKeySpec = new IvParameterSpec(initvectorByte);
Cipher aesCipherEnc = Cipher.getInstance("AES/CTR/PKCS5PADDING");
aesCipherEnc.init(Cipher.ENCRYPT_MODE, keySpec, ivKeySpec);
ciphertextByte = aesCipherEnc.doFinal(plaintextByte);
return ciphertextByte;
}
public static byte[] AesCtrNoPaddingDecryptBC(byte[] ciphertextByte, byte[] keyByte, byte[] initvectorByte)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException,
NoSuchProviderException {
byte[] decryptedtextByte = null;
SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
IvParameterSpec ivKeySpec = new IvParameterSpec(initvectorByte);
Cipher aesCipherDec = Cipher.getInstance("AES/CTR/NOPADDING", "BC");
aesCipherDec.init(Cipher.DECRYPT_MODE, keySpec, ivKeySpec);
decryptedtextByte = aesCipherDec.doFinal(ciphertextByte);
return decryptedtextByte;
}
public static byte[] AesCtrNoPaddingDecrypt(byte[] ciphertextByte, byte[] keyByte, byte[] initvectorByte)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
byte[] decryptedtextByte = null;
SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
IvParameterSpec ivKeySpec = new IvParameterSpec(initvectorByte);
Cipher aesCipherDec = Cipher.getInstance("AES/CTR/NOPADDING");
aesCipherDec.init(Cipher.DECRYPT_MODE, keySpec, ivKeySpec);
decryptedtextByte = aesCipherDec.doFinal(ciphertextByte);
return decryptedtextByte;
}
public static String printHexBinary(byte[] bytes) {
final char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}这是控制台输出:
AES mode CTR PKCS5PADDING or NOPADDING ?
keyByte (hex) :3132333435363738393031323334353637383930313233343536373839303132
initvectorByte (hex) :FA61736967A9DE5E86F7ED8F345E0C4D
plaintextString :HelloWorld12345
plaintextByte (hex) :48656C6C6F576F726C643132333435
= = = Encryption AES/CTR/PKCS5PADDING JCE = = =
ciphertextByte (hex) :5385A8F0BEC7FAC14FCC7AA2B04D9B
= = = Decryption AES/CTR/NOPADDING BC = = =
decryptedtextByte (hex):48656C6C6F576F726C643132333435
decryptedtextString :HelloWorld12345https://stackoverflow.com/questions/58917639
复制相似问题