如何在 Java 中使用 3DES 加密/解密一串文本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1645747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I encrypt/decrypt a string of text using 3DES in java?
提问by ScArcher2
Possible Duplicate:
How do I use 3des encryption/decryption in Java?
可能的重复:
如何在 Java 中使用 3des 加密/解密?
How do I encrypt/decrypt a string of text using 3DES in java?
如何在 Java 中使用 3DES 加密/解密一串文本?
I found my answer. Duplicate question that didn't show up when I asked this one.
我找到了我的答案。当我问这个问题时没有出现重复的问题。
回答by Kartoch
From an old code:
从旧代码:
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);
}
Notice than other usage of DESede are available in Java JDK 6:
请注意,Java JDK 6 中提供了 DESede 的其他用法:
- DESede/CBC/NoPadding (168)
- DESede/CBC/PKCS5Padding (168)
- DESede/CBC/NoPadding (168)
- DESede/CBC/PKCS5Padding (168)
There is also ECB mode available (but be carreful to not use it twice !!), you don't need to use iv part in this case:
还有ECB模式可用(但要小心不要使用两次!!),在这种情况下你不需要使用iv部分:
- DESede/ECB/NoPadding (168)
- DESede/ECB/PKCS5Padding (168)
- DESede/ECB/NoPadding (168)
- DESede/ECB/PKCS5Padding (168)
To generate key for DESede:
为 DESede 生成密钥:
KeyGenerator generatorDes = KeyGenerator.getInstance("DESede");
SecretKey skaes = generatorDes.generateKey();
Finally I recommand reading this documentfrom SUN if you need to work on Java and Cryptography
最后,如果您需要研究 Java 和密码学,我建议您从 SUN阅读此文档
回答by sfussenegger
We use this little helper class for password-based DES encryption from String to Hex String and back - not sure how to get this working with 3DES though:
我们使用这个小助手类进行基于密码的 DES 加密,从 String 到 Hex String 再返回——但不确定如何使用 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;
}
}
You would use this class like this:
你会像这样使用这个类:
public static void main(final String[] args) {
final DesHelper h = new DesHelper("blabla");
System.out.println(h.decrypt(h.encrypt("foobar")));
}
回答by Kushal Paudyal
I wrote an article on this sometimes back. Please visit the following link in my blog that has a working, completed code with explanations and diagram.
我有时会写一篇关于这个的文章。请访问我博客中的以下链接,该链接包含一个有效的、完整的代码以及解释和图表。
View My Triple DES Encryption Article, Code Here
Hopefully you will find it helpful.
希望你会发现它有帮助。
回答by David R Tribble
You may also consider using a stream cipher (e.g., OFB or CTR mode on top of a 3DES block encryption), so that you don't have to deal with padding the string to a multiple of the cipher blocksize.
您还可以考虑使用流密码(例如,在 3DES 块加密之上的 OFB 或 CTR 模式),这样您就不必处理将字符串填充为密码块大小的倍数的问题。

