【发布时间】:2018-11-28 19:27:45
【问题描述】:
我很难理解这里发生了什么。我是加密领域的新手,我试图在通过 HTTP 传输(以 JSON 字符串形式发送)之前对用户名和密码进行加密,然后在另一端对其进行解密。
我有一个类作为 AES 的简单实现(使用硬编码密钥/iv):
public class SimpleAES
{
private byte[] key = { 32, 128, 16, 11, 28, 36, 45, 15, 214, 184, 17, 244, 27, 142, 252, 119, 111, 84, 125, 244, 123, 93, 126, 39, 44, 76, 87, 118, 231, 136, 43, 109 };
private byte[] vector = { 246, 164, 231, 211, 32, 8, 64, 128, 211, 221, 132, 242, 122, 123, 129, 254 };
private ICryptoTransform encryptor, decryptor;
private UTF8Encoding encoder;
public SimpleAES()
{
//return;
RijndaelManaged rm = new RijndaelManaged();
encryptor = rm.CreateEncryptor(key, vector);
decryptor = rm.CreateDecryptor(key, vector);
encoder = new UTF8Encoding();
}
public string Encrypt(string unencrypted)
{
//return unencrypted;
return Convert.ToBase64String(Encrypt(encoder.GetBytes(unencrypted)));
}
public string Decrypt(string encrypted)
{
//return encrypted;
return encoder.GetString(Decrypt(Convert.FromBase64String(encrypted)));
}
public byte[] Encrypt(byte[] buffer)
{
return Transform(buffer, encryptor);
}
public byte[] Decrypt(byte[] buffer)
{
return Transform(buffer, decryptor);
}
protected byte[] Transform(byte[] buffer, ICryptoTransform transform)
{
MemoryStream stream = new MemoryStream();
using( CryptoStream cs = new CryptoStream(stream, transform, CryptoStreamMode.Write) )
{
cs.Write(buffer, 0, buffer.Length);
}
return stream.ToArray();
}
}
在我的 ASP.NET Core Web API(面向 Microsoft.AspNetCore 2.1.0)中,我有一个包含我的 SimpleAES 类的类库(面向 .NET Standard 2.0)。此类还存在于驱动我的 Xamarin.iOS 应用程序的类库中,该应用程序是使用最新稳定版本的 Xamarin.iOS 构建的,面向 iOS 11。
在 ASP.NET Core Web API 中,这是以下语句产生的结果(bs 是 SimpleAES 对象):
bs.Encrypt("testuser") --> dgIoOZ5UKsI2isPIbqXFNA==
bs.Encrypt("testpass") --> MZI72tKGu9VPIhF6vXoN4A==
bs.Encrypt("testuser72") --> gpzPtU6pTc6vuvpIaiwb1w==
bs.Encrypt("testpass1946") --> E3hamfb+u3AQ1Ip6KhC1gg==
在 Xamarin.iOS 应用程序中,这正是相同的语句产生的结果:
bs.Encrypt("testuser") --> dgIoOZ5UKsI2isPIbqXFNA==
bs.Encrypt("testpass") --> RCXKi1sGI1N/uiSNBI1JLA==
bs.Encrypt("testuser72") --> 7JVjuO3JNtKffSJCQ/Vndg==
bs.Encrypt("testpass1946") --> BROGP9AUByLcYFVtXS9FMg==
为什么这些值不同?我的理解是,使用相同的密钥、IV、模式和其他设置属性,AES 加密输出在任何给定字符串的任何实现中都是相同的。
此外,如果我每次更改 iOS 应用程序中的语句以创建一个新的 SimpleAES 对象,则加密输出正确地与我的 ASP.NET Core Web API 加密输出相同 .
对我来说,解决方案(不是一个好,也不是我想要的)是这样做:
bs.Encrypt("testuser") --> dgIoOZ5UKsI2isPIbqXFNA==
bs = new SimpleAES();
bs.Encrypt("testpass") --> MZI72tKGu9VPIhF6vXoN4A==
bs = new SimpleAES();
bs.Encrypt("testuser72") --> gpzPtU6pTc6vuvpIaiwb1w==
bs = new SimpleAES();
bs.Encrypt("testpass1946") --> E3hamfb+u3AQ1Ip6KhC1gg==
这会产生正确的加密。在 ASP.NET Core Web API 上,在每次加密之间创建一个新的 SimpleAES 对象,不会执行任何操作,并且值保持完全相同。
有谁知道为什么这会在 Xamarin.iOS 上以这种方式运行?也许是垃圾收集问题?代码中是否存在特定于 Xamarin.iOS 的问题?我只是不知所措,不想使用这个解决方案。
任何帮助将不胜感激。
【问题讨论】:
-
旁注:有什么理由不使用 ssl 证书来管理客户端/服务器之间的端到端加密(所以通过 httpS 发送)?
-
@Igor -- 我们正计划这样做。我已经在开发 SSL 证书上运行了 Web API。我被要求仍然在将用户名和密码传递给服务器和从服务器传递之前对其进行加密。我认为我们不需要这样做;然而,命令就是命令!
-
你是对的,如果你使用 SSL,那么你就不需要。添加一个 SSL 并告诉他们它已经完成,因为它完全加密了。 SSL 证书比您将构建的任何东西都要好(这对您的编码没有任何冒犯,只是它是由一个团队考虑、设计和发展的,其唯一目的是创建一种安全的数据传输方式。)
-
尝试加密几个字节数组。字符串的东西肯定会引入潜在的变量,例如系统特定的编码、换行符等。我怀疑这是问题所在,但很容易消除。
-
@zzxyz 我认为这是一个好主意,但我也认为我奇怪的解决方法将证明它不是系统特定的编码,而是它在
RijndaelManaged实现中或与CryptoStream或ICryptoTransform接口。不过,只是我的想法。我会试试你的建议。
标签: c# asp.net encryption xamarin.ios