我在理解这里发生的事情时遇到了一些麻烦。我是加密世界的新手,尝试通过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应用程序的类库中,该应用程序使用针对iOS 11的最新稳定版本的Xamarin.iOS构建。
在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的问题吗?我很茫然,不想使用此解决方案。
任何帮助将不胜感激。
答案 0 :(得分:3)
调用<string-array name="arraypowerunit" translatable="false">
<item>@string/array_power_unit_item_00</item>
<item>@string/array_power_unit_item_01</item>
<item>@string/array_power_unit_item_02</item>
<item>@string/array_power_unit_item_03</item>
</string-array>
之后,ICryptoTransform
的实现不一定是可重用的(TransformFinalBlock
关闭时会自动发生)。在创建具有相同变换的另一个CryptoStream
之前,应先检查CanReuseTransform
属性。
除了,正如刚刚提到的另一条评论所述,该框架的某些版本中存在一个错误,其中某些实现未为CryptoStream
返回正确的值。为了安全起见,您可能希望每次都重新创建对象。