【发布时间】:2015-11-30 13:09:36
【问题描述】:
我需要使用从密码生成的自定义密钥来加密一些数据。
必须是: 3DES 密码模式:ECB 填充模式:零
我找不到任何代码来做到这一点。谁能给我一个例子?
我试过了,它显示了以下错误
ERROR: java.security.InvalidAlgorithmParameterException: expected IV length of 0
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import javax.crypto.Cipher;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class Encryption {
public static int MAX_KEY_LENGTH = DESedeKeySpec.DES_EDE_KEY_LEN;
private static String ENCRYPTION_KEY_TYPE = "DESede";
private static String ENCRYPTION_ALGORITHM = "DESede/ECB/PKCS5Padding";
private final SecretKeySpec keySpec;
public Encryption(String passphrase) {
byte[] key;
try {
// get bytes representation of the password
key = passphrase.getBytes("UTF8");
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
}
key = padKeyToLength(key, MAX_KEY_LENGTH);
keySpec = new SecretKeySpec(key, ENCRYPTION_KEY_TYPE);
}
// !!! - see post below
private byte[] padKeyToLength(byte[] key, int len) {
byte[] newKey = new byte[len];
System.arraycopy(key, 0, newKey, 0, Math.min(key.length, len));
return newKey;
}
// standard stuff
public byte[] encrypt(byte[] unencrypted) throws GeneralSecurityException {
return doCipher(unencrypted, Cipher.ENCRYPT_MODE);
}
public byte[] decrypt(byte[] encrypted) throws GeneralSecurityException {
return doCipher(encrypted, Cipher.DECRYPT_MODE);
}
private byte[] doCipher(byte[] original, int mode) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
// IV = 0 is yet another issue, we'll ignore it here
IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 });
cipher.init(mode, keySpec, iv);
return cipher.doFinal(original);
}
}
编辑: 现在我有了这个,我将自定义密钥(密钥大小=8)作为“密码”参数传递 我调用的php不接受加密结果(不正确)。
正确的加密是这个网络将算法“三重”和模式:ECB https://www.tools4noobs.com/online_tools/encrypt/
我还不知道我做错了什么......
public class Encryption {
public static int MAX_KEY_LENGTH = DESedeKeySpec.DES_EDE_KEY_LEN;
private static String ENCRYPTION_KEY_TYPE = "DESede";
private static String ENCRYPTION_ALGORITHM = "DESede/ECB/NoPadding";
private final SecretKeySpec keySpec;
public Encryption(String passphrase) {
byte[] key;
try {
// get bytes representation of the password
key = passphrase.getBytes("UTF8");
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException(e);
}
key = padKeyToLength(key, MAX_KEY_LENGTH);
keySpec = new SecretKeySpec(key, ENCRYPTION_KEY_TYPE);
}
private byte[] padKeyToLength(byte[] key, int len) {
byte[] newKey = new byte[len];
System.arraycopy(key, 0, newKey, 0, Math.min(key.length, len));
return newKey;
}
// standard stuff
public byte[] encrypt(byte[] unencrypted) throws GeneralSecurityException {
return doCipher(unencrypted, Cipher.ENCRYPT_MODE);
}
public byte[] decrypt(byte[] encrypted) throws GeneralSecurityException {
return doCipher(encrypted, Cipher.DECRYPT_MODE);
}
private byte[] doCipher(byte[] original, int mode) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM);
int bs = cipher.getBlockSize();
byte[] padded = new byte[original.length + bs - original.length % bs];
System.arraycopy(original, 0, padded, 0, original.length);
cipher.init(mode, keySpec);
return cipher.doFinal(padded);
}
【问题讨论】:
-
您刚刚在互联网上发布了用于加密的密钥...
-
错误很明显:“预期 IV 长度为 0”。 ECB 模式不使用 IV,但您确实不应该使用 ECB。它在语义上不安全。对于每个加密,至少使用带有随机 IV 的 CBC 模式。 IV 不必是秘密的,因此您可以将其与密文一起发送,但它必须是不可预测的。
-
@Relequestual 我发布的密钥是一个示例,它不是真正的密钥。我不知道为什么有人对这个问题投了反对票。
-
@ArtjomB。我必须使用 ECB,因为我必须调用需要以 3DES 加密的数据的 php。
-
很公平。与您的其他评论有关。您无法控制您呼叫的系统吗?
标签: android security encryption 3des