我已经为此苦苦挣扎了几天。我需要使用采用加密参数的API。该API用C#编写。请求的加密如下:
算法:AES
密码模式:CBC
填充模式:PKCS7
块大小:128
密钥大小:256
Key:字符串->密钥是通过将提供的字符串转换为大小为32的字节数组来生成的:Encoding.ASCII.GetBytes(…)。 API声明字符串是使用字符串的MD5哈希函数由它们生成的。
IV:IV数组是通过将提供的字符串转换为大小为16的字节数组生成的:Encoding.ASCII.GetBytes(…)。
加密字符串的表示形式:Base64
在搜索并尝试了在线上建议的许多内容之后,我仍然无法生成相同的加密值(特别是默认情况下不支持PKCS7,而PKCS5应该工作相同,但事实并非如此)。这是我尝试过的一些事情:
1)使用充气城堡大罐使用PKCS7
2)添加JCE符合性,以便能够消除密钥和块大小的限制。
与他们联系后,他们向我发送了一个有效的android代码段(如果我在纯Java 8中运行,则会抱怨该提供程序(NoSuchAlgorithmException:找不到任何支持AES / CBC / PKCS7Padding的提供程序)):
public static String encrypt(String value) {
String plainText = value;
String escapedString;
try {
byte[] key = ENCRYPT_KEY.getBytes("UTF-8");
byte[] ivs = ENCRYPT_IV.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
AlgorithmParameterSpec paramSpec = new IvParameterSpec(ivs);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, paramSpec);
escapedString = Base64.encodeToString(cipher.doFinal(plainText.getBytes("UTF-8")), Base64.DEFAULT).trim();
return escapedString;
} catch (Exception e) {
e.printStackTrace();
return value;
}
}
请提供任何帮助。
这是我尝试过的代码片段:
package com.melhem.TestJava;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.Security;
import java.util.Base64;
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;
public class StringFunc {
final static String key = "API_KEY_32_CHARs";
final static String iv = "API_IV_16_CHARs";
final static String algorithm = "AES/CBC/PKCS7Padding";
private static Cipher cipher = null;
private static SecretKeySpec skeySpec = null;
private static IvParameterSpec ivSpec = null;
public static void main(String[] args) {
System.out.println(encrypt("STRING_TO_ENCODE"));
}
private static void setUp(){
try{
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
skeySpec = new SecretKeySpec(key.getBytes("ASCII"), "AES");
ivSpec = new IvParameterSpec(iv.getBytes("ASCII"));
cipher = Cipher.getInstance(algorithm);
}catch(NoSuchAlgorithmException | NoSuchPaddingException ex){
ex.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static String encrypt(String str){
try{
// Integer strL = (int) Math.ceil(str.length() / 8.0);
// Integer strB = strL*8;
// str = padRight(str, ' ', strB);
setUp();
try {
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
System.out.println("Block size: " + cipher.getBlockSize() * 8);
System.out.println("Algorithm name: " + cipher.getAlgorithm());
System.out.println("Key size: " + skeySpec.getEncoded().length * 8);
} catch (InvalidAlgorithmParameterException ex) {
ex.printStackTrace();
return "";
}
byte[] enc = cipher.doFinal(str.getBytes("ASCII"));
String s = new String(Base64.getEncoder().encode(enc));
s = s.replace("+", "__plus__");
s = s.replace("/", "__slash__");
return s;
}catch(InvalidKeyException | IllegalBlockSizeException | BadPaddingException ex){
ex.printStackTrace();
return "";
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return "";
}
}
public static String padRight(String msg, char x, int l) {
String result = "";
if (!msg.isEmpty()) {
for (int i=0; i<(l-msg.length()); i++) {
result = result + x;
}
result = msg + result;
}
return result;
}
}
答案 0 :(得分:0)
Java Cipher package仅支持PKCS#7填充; AES/CBC/PKCS5Padding
。使用这个;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
对于大多数分组密码,#5和#7可以互换。请参阅Crypto.StackExchange
上的问题,并且用于使用256位密钥大小的AES;
Java标准密码库限制为128位密钥大小。您必须去下载Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6