C# 到 Java DES 加密
Posted
技术标签:
【中文标题】C# 到 Java DES 加密【英文标题】:C# to Java DES encryption 【发布时间】:2017-03-08 07:15:42 【问题描述】:尝试创建 java 类,该类将像下面的 C# 代码一样加密和解密。
以下是我的 C# 代码,我需要将其转换为 Java。有人可以帮我怎么做吗?
我已经这样做了将近 2 天,但找不到任何关于如何转换它的解决方案。我是加密新手。
注意 - 似乎 C# 代码使用了 ACME 库。但在我的 java 中,我不应该使用 ACME jar 文件。
public static string EncryptBase64(string key, string clearText)
if (key.Length > 8)
key = key.Substring(0, 8);
byte[] keyBytes = System.Text.Encoding.ASCII.GetBytes(key);
byte[] clearBytes = GetClearTextBytes(clearText);
// calculate the number of legitimate bytes in the last block
byte lastByte = (byte)(8 - (clearBytes.Length - textEncoding.GetByteCount(clearText)));
MemoryStream ms = new MemoryStream();
DES des = new DESCryptoServiceProvider();
des.Padding = PaddingMode.None;
des.GenerateIV();
System.Security.Cryptography.ICryptoTransform ict = des.CreateEncryptor(keyBytes, des.IV);
CryptoStream cs = new CryptoStream(ms, ict, CryptoStreamMode.Write);
cs.Write(clearBytes, 0, clearBytes.Length);
cs.FlushFinalBlock();
ms.Close();
byte[] cipherBytes = ms.ToArray();
// create a byte output stream for Acme compatibality
MemoryStream acmeCompatStream = new MemoryStream();
// Acme writes the IV to the frist block
acmeCompatStream.Write(des.IV, 0, 8);
for (int i = 0; i < cipherBytes.Length; i = i + 8)
// write the next block
acmeCompatStream.Write(cipherBytes, i, 8);
// write the number of valid bytes in the block
if (i == cipherBytes.Length - 8)
acmeCompatStream.WriteByte(lastByte);
else
acmeCompatStream.WriteByte(8);
acmeCompatStream.Close();
cipherBytes = acmeCompatStream.ToArray();
return (System.Convert.ToBase64String(cipherBytes));
以下是我在 java 中尝试过的代码。我有两种不同的加密功能。这两种加密方法我都试过了。但是两者都没有给出预期的加密字符串以在 acme 中解密。
package com.abc.some.common.nativeDES;
import java.io.ByteArrayOutputStream;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.xml.bind.DatatypeConverter;
public class DESEncrypt
public String keyValue = "123456789";
public static void main(String[] args)
String text = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><SomeRequest><OrderNumber>1564578</OrderNumber></SomeRequest>";
String codedtext ="not encrypted";
try
codedtext = new DESEncrypt().Encrypt1(text);
//codedtext = new DESEncrypt().encrypt(text);
catch (Exception e)
System.out.println("Exception in Encryption.. " + e.getMessage());
System.out.println(codedtext);
public String Encrypt1(String CXML)
try
KeySpec myKey = new DESKeySpec(keyValue.getBytes("UTF8"));
SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(myKey);
Cipher ecipher = Cipher.getInstance("DES");
ecipher.init(Cipher.ENCRYPT_MODE, key);
byte[] data = CXML.getBytes("ASCII");
Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, key);
byte[] crypt = ecipher.doFinal(data);
//String encoded = DatatypeConverter.printBase64Binary(crypt.toString().getBytes("ASCII"));
//String encoded = DatatypeConverter.printBase64Binary(crypt.getBytes("ASCII"));
String encoded = DatatypeConverter.printBase64Binary(crypt).toString();
System.out.println(encoded);
return encoded;
catch (Exception ex)
return null;
但我使用下面的 java 文件来加密使用 acme jar 文件的字符串。这按预期工作。但根据我的项目要求,我不应该使用外部(ACME)jar 文件。
package com.abc.common.encryption;
import java.io.FileInputStream;
import java.util.Properties;
import Acme.Crypto.SecurityDES;
public class ESBCryptoDES
public static void main(String args[])
// DESEncrypt("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><SomeRequest><OrderNumber>1564578</OrderNumber></SomeRequest>"
// ,"D:\\name\\proj\\order\\Encryption\\st.properties");
DESDecrypt("vQ9C7ZrLzjQpHvZjtHvUb0mFCr824/aClY2jKbeciczsRVr+kEETFvDuHgdBS/aLskYV3WX3U5TANSlK3pH80r3xOyn9Q8rTjlB/yXyU7J9MgibJ66jJx0wrqeloAkmQzqj+b5+I/lXANSlK3pH80kT1D+jqWAeV"
,"D:\\name\\proj\\order\\Encryption\\stDecrypt.properties");
public static String DESEncrypt(String SourceStrForCrypt,String PropPath)
String encrypt = "";
String decrypt = "";
// Load the property file.
Properties prop = new Properties();
try
FileInputStream in = new FileInputStream(PropPath);
prop.load(in);
in.close();
catch (Exception e)
System.out.println("Exception in loading property file.. "
+ e.getMessage());
// Encrypt the given content.
try
String keypath = prop.getProperty("proj.sample.DEV");
System.out.println("sample" + keypath);
String SourceToEncrypt = SourceStrForCrypt; //This will provide the xml string to encrypt
// Encryption
encrypt = SecurityDES.DesEncryptBase64(keypath,SourceToEncrypt);
System.out.println(encrypt);
// Decryption
decrypt = SecurityDES.DesDecryptBase64(keypath, encrypt);
System.out.println(decrypt);
catch (Exception e)
System.out.println("Exception in Encryption.. " + e.getMessage());
return encrypt;
public static String DESDecrypt(String SourceStrForCrypt,String PropPath)
// TODO Auto-generated method stub
String decrypt = "";
Properties prop = new Properties();
try
FileInputStream in = new FileInputStream(PropPath);
prop.load(in);
in.close();
catch (Exception e)
System.out.println("Exception in loading property file.. "+ e.getMessage());
try
String abc_keyPath = prop
.getProperty("proj.abc.DEV");
System.out.println("keypath" + abc_keyPath);
// Decryption
decrypt = SecurityDES.DesDecryptBase64(abc_keyPath, SourceStrForCrypt);
System.out.println("decrypted..."+decrypt);
catch (Exception e)
System.out.println("Exception in Encryption.. " + e.getMessage());
return decrypt;
【问题讨论】:
向我们展示您的尝试,并准确告诉我们问题所在。 *** 不是代码转换服务。而且你不应该使用 DES。 如果您使用 ACME 表示内置,也就是您应该自己编写 DES(大概是作为家庭作业),那么请参阅 FIPS PUB 46(-3) 了解算法和 NIST SP 800-17(附录A) 用于测试验证。 -- 如果你不应该自己编写 DES,你至少需要解释你想出的错误答案。 @JBNizet .. 我很抱歉没有分享我尝试过的 java 工作。用我尝试过的 java 代码更新了我的问题。你能说明一下我的 java 代码出了什么问题吗? 【参考方案1】: 调用doFinal()
两次没有意义。
打印byte[].toString()
的值没有意义。它不包含密文。
将其转换为 base-64 没有意义。它仍然不包含密文。
您需要将第一个doFinal()
调用直接返回的byte[]
数组转换为base-64,而不需要调用toString()
引起的往返String()
然后是`getBytes()。
NB 出于某种原因,您的 decrypt 方法中有一个名为 encrypt
的变量,并且出于一些更奇怪的原因,您返回它而不是 decrypt
,它实际上是唯一的变量包含明文。
【讨论】:
我已根据您的 cmets 更新了我的代码。仍然当我调用 base64 而不转换为字符串时,会引发错误。我已经尝试过如下声明。 //字符串编码 = DatatypeConverter.printBase64Binary(crypt.toString().getBytes("ASCII"));字符串编码 = DatatypeConverter.printBase64Binary(crypt.getBytes("ASCII")); 叹息。打字前请三思。crypt
已经是 byte[]
。我特别说“将它直接转换为base-64”。您无需执行任何操作即可将其作为byte[]
获取。而你不能。编译器刚刚告诉你。注意它没有“给你一个错误”。编译器消息被打印,而不是被抛出。运行时抛出异常。思路清晰,报告内容清晰。
我接受我的错误并根据您的 cmets 更新了我的 java 代码。尝试了一些类似下面的东西。字符串编码 = DatatypeConverter.printBase64Binary(crypt).toString();现在我得到了一些加密的字符串,我尝试使用 ACME jar 类解密它,它给我一个错误,说“加密的字节长度:120 无效的密文字节数”
DatatypeConverter.printBase64Binary()
的输出类型是什么?以及为什么需要将其转换为String
?
删除了字符串转换,正如您所提到的,它不是必需的。以上是关于C# 到 Java DES 加密的主要内容,如果未能解决你的问题,请参考以下文章
java的 DES 加密解密方法 求对应C#的加密解密方法,急切