如何在java中使用3DES加密/解密文本字符串?
可能重复:如何在java中使用3DES加密/解密文本字符串?,java,encryption,3des,Java,Encryption,3des,可能重复: 如何在java中使用3DES加密/解密文本字符串 我找到了答案。重复的问题,当我问这个问题时没有出现 来自旧代码: public void testSymCypher(SecretKey k, String str) throws BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException,
如何在java中使用3DES加密/解密文本字符串
我找到了答案。重复的问题,当我问这个问题时没有出现 来自旧代码:
public void testSymCypher(SecretKey k, String str)
throws BadPaddingException, IllegalBlockSizeException,
InvalidAlgorithmParameterException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchPaddingException
{
Cipher cip = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cip.init(Cipher.ENCRYPT_MODE,k);
byte[] ciphered = cip.doFinal(str.getBytes());
byte iv[] = cip.getIV();
// printing the ciphered string
printHexadecimal(ciphered);
IvParameterSpec dps = new IvParameterSpec(iv);
cip.init(Cipher.DECRYPT_MODE,k,dps);
byte[] deciphered = cip.doFinal(ciphered);
// printing the deciphered string
printHexadecimal(deciphered);
}
请注意,Java JDK 6中提供了DESede的其他用法:
- DESede/CBC/NoPadding(168)
- DESede/CBC/PKCS5添加(168)
- DESede/ECB/NoPadding(168)
- DESede/ECB/PKCS5新增(168)
KeyGenerator generatorDes = KeyGenerator.getInstance("DESede");
SecretKey skaes = generatorDes.generateKey();
最后,如果您需要从旧代码中学习Java和密码,我建议您阅读SUN:
public void testSymCypher(SecretKey k, String str)
throws BadPaddingException, IllegalBlockSizeException,
InvalidAlgorithmParameterException, InvalidKeyException,
NoSuchAlgorithmException, NoSuchPaddingException
{
Cipher cip = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cip.init(Cipher.ENCRYPT_MODE,k);
byte[] ciphered = cip.doFinal(str.getBytes());
byte iv[] = cip.getIV();
// printing the ciphered string
printHexadecimal(ciphered);
IvParameterSpec dps = new IvParameterSpec(iv);
cip.init(Cipher.DECRYPT_MODE,k,dps);
byte[] deciphered = cip.doFinal(ciphered);
// printing the deciphered string
printHexadecimal(deciphered);
}
请注意,Java JDK 6中提供了DESede的其他用法:
- DESede/CBC/NoPadding(168)
- DESede/CBC/PKCS5添加(168)
- DESede/ECB/NoPadding(168)
- DESede/ECB/PKCS5新增(168)
KeyGenerator generatorDes = KeyGenerator.getInstance("DESede");
SecretKey skaes = generatorDes.generateKey();
最后,如果您需要使用Java和加密技术,我建议您阅读SUN的文章我们使用这个小助手类对基于密码的DES加密从字符串到十六进制字符串再到字符串进行加密-但不确定如何使用3DES实现这一点:
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class DesHelper {
private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DesHelper.class);
static final byte[] SALT = { (byte) 0x09, /* snip - randomly chosen but static salt*/ };
static final int ITERATIONS = 11;
private Cipher _ecipher;
private Cipher _dcipher;
public DesHelper(final String passphrase) {
try {
final PBEParameterSpec params = new PBEParameterSpec(SALT, ITERATIONS);
final KeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
final SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES")
.generateSecret(keySpec);
_ecipher = Cipher.getInstance(key.getAlgorithm());
_dcipher = Cipher.getInstance(key.getAlgorithm());
_ecipher.init(Cipher.ENCRYPT_MODE, key, params);
_dcipher.init(Cipher.DECRYPT_MODE, key, params);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
public String encrypt(final String string) {
try {
// Encode the string into bytes using utf-8
final byte[] bytes = string.getBytes("UTF-8");
// Encrypt
final byte[] enc = _ecipher.doFinal(bytes);
// Encode bytes to base64 to get a string
return bytesToHex(enc);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
public String decrypt(final String str) {
try {
// Decode base64 to get bytes
final byte[] dec = hexToBytes(str);
// Decrypt
final byte[] utf8 = _dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (final Exception e) {
log.info("decrypting string failed: " + str + " (" + e.getMessage() + ")");
return null;
}
}
private static String bytesToHex(final byte[] bytes) {
final StringBuilder buf = new StringBuilder(bytes.length * 2);
for (final byte b : bytes) {
final String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
buf.append("0");
}
buf.append(hex);
}
return buf.toString();
}
private static byte[] hexToBytes(final String hex) {
final byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
}
return bytes;
}
}
我们使用这个小助手类进行基于密码的DES加密,从字符串到十六进制字符串,再到字符串-不知道如何使用3DES实现这一点:
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class DesHelper {
private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DesHelper.class);
static final byte[] SALT = { (byte) 0x09, /* snip - randomly chosen but static salt*/ };
static final int ITERATIONS = 11;
private Cipher _ecipher;
private Cipher _dcipher;
public DesHelper(final String passphrase) {
try {
final PBEParameterSpec params = new PBEParameterSpec(SALT, ITERATIONS);
final KeySpec keySpec = new PBEKeySpec(passphrase.toCharArray());
final SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES")
.generateSecret(keySpec);
_ecipher = Cipher.getInstance(key.getAlgorithm());
_dcipher = Cipher.getInstance(key.getAlgorithm());
_ecipher.init(Cipher.ENCRYPT_MODE, key, params);
_dcipher.init(Cipher.DECRYPT_MODE, key, params);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
public String encrypt(final String string) {
try {
// Encode the string into bytes using utf-8
final byte[] bytes = string.getBytes("UTF-8");
// Encrypt
final byte[] enc = _ecipher.doFinal(bytes);
// Encode bytes to base64 to get a string
return bytesToHex(enc);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
public String decrypt(final String str) {
try {
// Decode base64 to get bytes
final byte[] dec = hexToBytes(str);
// Decrypt
final byte[] utf8 = _dcipher.doFinal(dec);
// Decode using utf-8
return new String(utf8, "UTF8");
} catch (final Exception e) {
log.info("decrypting string failed: " + str + " (" + e.getMessage() + ")");
return null;
}
}
private static String bytesToHex(final byte[] bytes) {
final StringBuilder buf = new StringBuilder(bytes.length * 2);
for (final byte b : bytes) {
final String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
buf.append("0");
}
buf.append(hex);
}
return buf.toString();
}
private static byte[] hexToBytes(final String hex) {
final byte[] bytes = new byte[hex.length() / 2];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16);
}
return bytes;
}
}
我写了一篇关于这方面的文章,有时还写了回来。请访问我博客中的以下链接,该链接有一个可用的、完整的代码以及解释和图表
希望你会发现它很有帮助。我曾经写过一篇关于这方面的文章。请访问我博客中的以下链接,该链接有一个可用的、完整的代码以及解释和图表
希望你会发现它有帮助。
你也可以考虑使用流密码(例如,在3DES块加密之上的OFB或CTR模式),这样你就不必处理将字符串填充到密码块大小的倍数。你也可以考虑使用流密码(例如,在3DES块加密之上的OFB或CTR模式)。这样您就不必将字符串填充到密码块大小的倍数。
这段代码为我提供了一个java.security.InvalidKeyException:无效密钥长度:com.sun.crypto.provider.desedeciper.engineGetKeySize(DashoA13*)上的8字节。我想这是因为我在KeyGenerator上犯了一个错误:它是DESede而不是DES。如果您使用自己的密钥,请检查密钥大小(它似乎与您使用的3DES密钥的类型有关。因为我对它不太了解,请参阅3DES的wikipedia页面)。此代码为我提供了一个java.security.InvalidKeyException:无效密钥长度:8字节,位于com.sun.crypto.provider.desedecyper.engineGetKeySize(DashoA13*)我想这是因为我在KeyGenerator上犯了一个错误:它是DESede而不是DES。如果您使用自己的密钥,请检查密钥大小(它似乎与您使用的3DES密钥类型有关。因为我对它了解不多,请参阅3DES的wikipedia页面)。