过去几天,我一直在尝试移植用于登录 Wizards of the Coast Character Builder API 的简单加密(找到 here)(这样我的应用程序就可以直接从服务器)到我可以在 Windows 8 Metro 应用程序中使用的东西,因为 AesManaged 没有进入 Metro 加密库。鉴于我充其量只是一名新手程序员,事实证明这超出了我的能力范围。
这是我需要移植的代码:
public static byte[] SimpleEncrypt(string value, string key)
{
byte[] buffer2;
ICryptoTransform transform = GetSimpleAlgorithm(key).CreateEncryptor();
using (MemoryStream stream = new MemoryStream())
{
using (CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Write))
{
byte[] bytes = Encoding.UTF8.GetBytes(value);
stream2.Write(bytes, 0, bytes.Length);
stream2.Flush();
stream2.FlushFinalBlock();
stream.Position = 0L;
buffer2 = stream.ToArray();
}
}
return buffer2;
}
private static SymmetricAlgorithm GetSimpleAlgorithm(string key)
{
AesManaged aes = new AesManaged();
byte[] source = new SHA256Managed().ComputeHash(Encoding.UTF8.GetBytes(key));
return new AesManaged { Key = source, IV = source.Take<byte>((aes.BlockSize / 8)).ToArray<byte>() };
}
这用于在通过登录之前加密密码:
contentClient.Login(username, SimpleEncrypt(password, username));
如果需要,Web 服务位于:http://ioun.wizards.com/ContentVault.svc
在第一个链接上面那个链接的评论中,有人在二月份建议了一些适用于 Windows 8 的代码,但是说代码有一些问题我必须在它编译之前解决,即使那样,当我尝试使用它登录,但我从服务返回异常,提示“填充无效且无法删除”。
这是我目前正在使用的:
private static byte[] SimpleEncrypt(string value, string key)
{
var simpleAlgorithm = GetSimpleAlgorithm(key);
var encryptedBuffer = CryptographicEngine.Encrypt(simpleAlgorithm.Item1, CryptographicBuffer.ConvertStringToBinary(value, BinaryStringEncoding.Utf8), simpleAlgorithm.Item2);
var result = new byte[encryptedBuffer.Length];
CryptographicBuffer.CopyToByteArray(encryptedBuffer, out result);
return result;
}
private static Tuple<CryptographicKey, IBuffer> GetSimpleAlgorithm(string key)
{
var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
var keyAsBinary = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
var source = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256).HashData(keyAsBinary);
var shortKey = CryptographicBuffer.CreateFromByteArray(UTF8Encoding.UTF8.GetBytes(key).Take((int)provider.BlockLength).ToArray());
return new Tuple<CryptographicKey,IBuffer>(provider.CreateSymmetricKey(source), shortKey);
}
我们将不胜感激为使这项工作提供任何帮助。
最佳答案
好吧,多花点时间看了,发现问题了。
建议的更新版本使用“key”字符串创建 IV,而它本应使用 key 的哈希值。
这是功能版本,以防有人需要:
private static byte[] SimpleEncrypt(string value, string key)
{
var simpleAlgorithm = GetSimpleAlgorithm(key);
CryptographicKey encryptKey = simpleAlgorithm.Item1;
IBuffer IV = simpleAlgorithm.Item2;
var encryptedBuffer = CryptographicEngine.Encrypt(encryptKey, CryptographicBuffer.ConvertStringToBinary(value, BinaryStringEncoding.Utf8), IV);
var result = new byte[encryptedBuffer.Length];
CryptographicBuffer.CopyToByteArray(encryptedBuffer, out result);
return result;
}
private static Tuple<CryptographicKey, IBuffer> GetSimpleAlgorithm(string key)
{
var provider = SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmNames.AesCbcPkcs7);
var keyAsBinary = CryptographicBuffer.ConvertStringToBinary(key, BinaryStringEncoding.Utf8);
var source = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256).HashData(keyAsBinary);
byte[] sourceArray = new byte[source.Length];
CryptographicBuffer.CopyToByteArray(source, out sourceArray);
var shortKey = CryptographicBuffer.CreateFromByteArray(sourceArray.Take((int)provider.BlockLength).ToArray());
return new Tuple<CryptographicKey,IBuffer>(provider.CreateSymmetricKey(source), shortKey);
}
关于c# - 端口DDI登录密码加密到Metro,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13235458/