C#(加密)和Java(解密)之间的AES加密/解密
我有一个C#应用程序来调用Java Web服务来验证用户的密码。我想让C#应用程序加密密码,然后让Java Web服务解密密码。我已经完成了Java方面的代码(解密代码),但我无法弄清楚C#代码来加密代码。C#(加密)和Java(解密)之间的AES加密/解密
这是我的Java代码...
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);
}
这里是我发现使用C#进行加密,但由于我的Java功能,所以我的Java Web服务是无法也不会产生相同的encrypion串解密它。
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);
}
我不介意改变我的Java Web服务解密的方式,以使其与我的C#应用程序一起工作。
我试图避免使用SSL,因为我不知道该如何去那个方向去调用一个方法。
在任何情况下,我发现这个网站和代码的作品非常漂亮。我能够在C#端加密/散列用户的密码,并让Java端将其转换回来。
http://zenu.wordpress.com/2011/09/21/aes-128bit-cross-platform-java-and-c-encryption-compatibility/
另外还有一点也有伟大工程的例子这个其他网站...
http://blogs.msdn.com/b/dotnetinterop/archive/2005/01/24/java-and-net-aes-crypto-interop.aspx
在C#中,您正在使用DeriveBytes
函数从密码获取密钥,而在Java中,您直接将密码用作密钥。
这样你显然在双方都有不同的关键。不要这样做,在双方使用相同的密钥派生函数。
“你做错了”。
如果需要通过发送一个密码(如果例如Java系统需要通过对密码又一方),只需使用你的C#应用程序和Java应用程序之间的SSL,而忘记了添加额外的加密。大多数人最终会遇到一个或多个实施错误,这会使系统容易受到攻击。
如果Java方面只需要验证C#客户端是否有权访问它,那么很可能比发送明文密码短语更好 - 这取决于您需要授权的方式。这也是您应该努力使用久经考验的代码的一个领域,因为即使您对加密基础知识有相当的理解,也很容易搞砸。
获得Java和C#之间的AES通信工作(即按照原样回答您的问题)是一项足够有趣的任务(我会让其他人处理:)),但是如果您想要安全性,请使用其他方法。
一般来说,密码是散列而不是加密的(例如,使用SHA-2算法之一,例如SHA-256),所以如果我正确理解您的要求,那么我将不得不异议您技术方法在这种情况下。
我同意另一个用户,他建议使用已知的安全交换方法(如SSL/TLS)来进行端点之间的安全通信。
是的,我想我对加密这个术语的使用在技术上可能并不正确,但我想每个人都会明白我在这里要做的事情。 –
我是一个相当随便SO用户,我看问定期质询的确切类型。请在SO中搜索以下内容:'aes c#java'或者现在您已经提出了该问题,请查看右栏中的相关问题。 –
@Eric J有700多个答案,我不太确定你是否有资格成为休闲用户;) – Nate
@Nate:也许我只是有一个Skeet自卑感。 –