这几天我一直在纠结。我需要使用一个接受加密参数的API。API是用C#编写的。请求的加密如下:
算法:AES
密码模式:CBC
填充模式:PKCS7
块大小:128
密钥大小:256
加密字符串的表示形式:Base64
在搜索和尝试了网上建议的那么多东西之后,我仍然无法生成相同的加密值(特别是默认情况下不支持PKCS7,而PKCS5应该工作相同,但事实并非如此)。以下是我尝试过的一些方法:
1)使用bouncy castle jar来使用PKCS7
2)添加JCE遵从性以能够消除对键和块大小的限制。
与他们联系后,他们给我发送了一个正在工作的android代码段(如果我运行在普通java 8中,该代码段会抱怨提供程序(NoSuchAlgorithmException:找不到任何支持AES/CBC/PKCS7Padding)):(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;
}
}
Java密码包仅支持使用aes/cbc/pkcs5padding
填充PKCS#7。这不是一个好的命名,因为PKCS#5填充支持8字节的块大小,而DES和PKCS#7最多支持255字节。对于Java,请使用这个;
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
对于最现代的分组密码,#5和#7是不可互换的,因为AES是128位分组密码。请参阅关于Crypto.StackExchange的问题。
以及,用于使用具有256位密钥大小的AES;
Java标准密码库限制为128位密钥大小。您必须下载Java加密扩展(JCE)无限强度管辖策略文件6
我在使用java AES/CBC/PKCS7Padding加密时遇到了问题。我已经在使用提供程序之前进行搜索和跟踪。但我还是无法得到正确的加密 假设要求是: 加密类型:对称 算法:AES 块大小=128Bit(16字节) 密码模式:CBC 填充模式:PKCS7 加密密钥长度:256 Bit(32字节) 向量初始化长度(IV):128 Bit(16字节) 示例: 普通数据=ABC123 加密数据(b
以下示例有什么问题? 问题是解密字符串的第一部分是无意义的。不过,其余的都很好,我明白了...
我最近在Java中使用了AES CBC 128算法来加密数据。现在我需要用PHP重建算法,但我不知道如何重建,因为互联网上的PHP算法返回不同的结果。也许你能帮我。 这是要加密的Java代码: 这是我的php代码: 当我从java加密加密数据时,此结果无法在Php解密上解密。 你们能帮我构建一个PHP脚本吗?它可以返回与java加密相同的结果?
问题内容: 我目前正在使用 256个字节的* 密钥大小来用Java加密文件,但是在搜索时我在stackexchange PKCS#5-PKCS#7填充上发现了它,并提到: * PKCS#5填充是8个字节块大小的PKCS#7填充的子集 所以我想知道 相对于上述配置,性能会更好吗? 正如我们所提到的,我们如何在Java中配置块大小 PKCS#7填充适用于从1到255字节的任何块大小。 我的示例代码是
我尝试使用“RSA/ECB/PKCS7Padding”进行加密。JCE不支持它。所以我下载了Bouncy Castle,但Bouncy Castle似乎也不支持这种转换。以下代码: 投掷 我做得对吗? 蒂亚。