C#(加密)和Java(解密)之间的AES加密/解密
我有一个C#应用程序来调用Java web服务来验证用户的密码。我希望让C#应用程序加密密码,然后让Java web服务解密密码。我已经完成了Java端的代码(解密代码),但我无法找出加密代码的C代码 这是我的Java代码C#(加密)和Java(解密)之间的AES加密/解密,c#,java,aes,encryption,C#,Java,Aes,Encryption,我有一个C#应用程序来调用Java web服务来验证用户的密码。我希望让C#应用程序加密密码,然后让Java web服务解密密码。我已经完成了Java端的代码(解密代码),但我无法找出加密代码的C代码 这是我的Java代码 public void validateUserPassword(String encryptedPassword) { String algorithm = "AES"; SecretKeySpec keySpec = null; byte[] k
public void validateUserPassword(String encryptedPassword) {
String algorithm = "AES";
SecretKeySpec keySpec = null;
byte[] key = "<==OMGWTFBBQ!==>".getBytes();
Cipher cipher = null;
cipher = Cipher.getInstance(algorithm);
keySpec = new SecretKeySpec(key, algorithm);
byte[] encryptionBytes = new sun.misc.BASE64Decoder().decodeBuffer(encryptedPassword);
cipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] recoveredBytes = cipher.doFinal(encryptionBytes);
String recovered = new String(recoveredBytes);
log.info("Encrypted password: " + encryptedPassword);
log.info("Dencrypted password: " + recovered);
}
public void validateUserPassword(字符串加密密码){
字符串算法=“AES”;
SecretKeySpec keySpec=null;
byte[]key=“.getBytes();
密码=空;
cipher=cipher.getInstance(算法);
keySpec=新的SecretKeySpec(键,算法);
byte[]encryptionBytes=new sun.misc.BASE64Decoder().decodeBuffer(encryptedPassword);
cipher.init(cipher.DECRYPT_模式,keySpec);
byte[]recoveredBytes=cipher.doFinal(encryptionBytes);
恢复的字符串=新字符串(恢复的字节);
log.info(“加密密码:“+encryptedPassword”);
log.info(“加密密码:+已恢复”);
}
这里有一些我发现可以使用C#加密的东西,但是它不会产生与我的Java函数相同的encrypion字符串,因此我的javaweb服务无法解密它
private void btnEncrypt_Click(object sender, EventArgs e)
{
string PlainText = "testing";
string Password = "<==OMGWTFBBQ!==>";
string Salt = "Kosher";
string HashAlgorithm = "SHA1";
int PasswordIterations = 2;
string InitialVector = "OFRna73m*aze01xY";
int KeySize = 256;
string encryptedPassword;
byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);
PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);
byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
RijndaelManaged SymmetricKey = new RijndaelManaged();
SymmetricKey.Mode = CipherMode.CBC;
byte[] CipherTextBytes = null;
using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes))
{
using (MemoryStream MemStream = new MemoryStream())
{
using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
{
CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
CryptoStream.FlushFinalBlock();
CipherTextBytes = MemStream.ToArray();
MemStream.Close();
CryptoStream.Close();
}
}
}
SymmetricKey.Clear();
encryptedPassword = Convert.ToBase64String(CipherTextBytes);
MessageBox.Show("Encrypted password: " + encryptedPassword);
}
private void btnEncrypt\u单击(对象发送方,事件参数e)
{
string PlainText=“测试”;
字符串密码=”;
string Salt=“犹太教”;
字符串HashAlgorithm=“SHA1”;
int PasswordIterations=2;
字符串InitialVector=“OFRna73m*aze01xY”;
int KeySize=256;
字符串加密密码;
byte[]InitialVectorBytes=Encoding.ASCII.GetBytes(InitialVector);
byte[]SaltValueBytes=Encoding.ASCII.GetBytes(Salt);
字节[]明文字节=Encoding.UTF8.GetBytes(明文);
PasswordDeriveBytes DerivedPassword=新的PasswordDeriveBytes(密码、SaltValueBytes、哈希算法、密码迭代);
byte[]KeyBytes=DerivedPassword.GetBytes(KeySize/8);
RijndaelManaged SymmetricKey=新的RijndaelManaged();
SymmetricKey.Mode=CipherMode.CBC;
byte[]CipherTextBytes=null;
使用(ICryptoTransform Encryptor=SymmetricKey.CreateEncryptor(KeyBytes,InitialVectorBytes))
{
使用(MemoryStream MemStream=new MemoryStream())
{
使用(CryptoStream CryptoStream=new CryptoStream(MemStream、Encryptor、CryptoStreamMode.Write))
{
CryptoStream.Write(明文字节,0,明文字节.Length);
CryptoStream.FlushFinalBlock();
CipherTextBytes=MemStream.ToArray();
MemStream.Close();
CryptoStream.Close();
}
}
}
SymmetricKey.Clear();
encryptedPassword=Convert.tobase64字符串(密文字节);
MessageBox.Show(“加密密码:+encryptedPassword”);
}
我不介意改变Java web服务的解密方式,以使其与我的C#应用程序一起工作。在C#中,您使用DeriveBytes
函数从密码中获取密钥,而在Java中,您直接使用密码作为密钥
这样,两边的键显然不同。不要这样做,在两侧使用相同的键派生函数。“你做错了”
如果需要发送密码短语(例如,如果java系统需要将密码短语传递给另一方),只需在C#应用程序和java应用程序之间使用SSL,而不用再添加额外的加密。大多数人最终会出现一个或多个实现错误,这将使系统易受攻击
如果Java端只需要验证C#客户端是否被授权访问它,那么很可能有一种比发送明文密码更好的方法——这取决于您需要针对哪些内容进行授权。这也是您应该努力使用经过测试的代码的一个领域,因为即使您对加密基本原理有了很好的理解,也很容易搞糟
让Java和C#之间的AES通信正常工作(即按原样回答您的问题)是一项非常有趣的任务(我将让其他人处理:),但如果您想要安全性,请使用另一种方法。一般来说,密码是散列的,而不是加密的(例如,使用SHA-2算法之一,如SHA-256),因此,如果我正确理解了您的需求,那么在这种情况下,我将不得不反对您的技术方法
我同意另一位用户的意见,他建议使用已知的安全交换方法(如SSL/TLS)来实现端点之间的安全通信。我试图避免使用SSL,因为我不知道只需要一次方法调用就可以实现这个方向 无论如何,我发现这个网站和代码工作得很好。我能够在C端加密/散列用户密码,并让Java端将其转换回来 还有另外一个网站也有一个很好的例子
我是一个相当随意的SO用户,我经常会遇到这种类型的问题。请在SO中搜索以下内容:
aes c#java
,或者,既然您已经提出了问题,请查看右侧栏中的相关问题。@Eric J回答了700多个问题,我不确定您是否符合临时用户的资格;)@内特:也许我只是有一种双向飞碟自卑情结。@Eric J他们属于自己的联盟。是的,我想我使用的术语加密在技术上可能不正确,但我想每个人都明白我在这里要做的事情的要点。