端口DDI登录密码加密到Metro

时间:2012-11-05 15:42:37

标签: c# encryption microsoft-metro

过去几天我一直在尝试移植用于登录海岸向导角色生成器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);
}

任何帮助实现这项工作的人都会非常感激。

1 个答案:

答案 0 :(得分:1)

Welp,花了更多的时间来查看它,并找出问题所在。

建议的更新版本使用“key”字符串来创建IV,而它应该使用密钥的哈希值。

这是功能版本,万一有人想要它:

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);
}