[英]Manually decrypt data encrypted with MachineKey.Protect
我正在嘗試手動解密使用MachineKey.Protect()加密的數據。 我正在使用AES和SHA1算法。
// unencrypted input in HEX: 010203
// AES key in HEX: CCA0DC9874B3F9E679E0A576F77EDF9B121CAB2F9A363A4EAF99976F7B51FA89
// want to decrypt this: A738E5F98920E37AB14C5F4332D4C7F0EC683680AAA0D34B806E75DECF04B7A3DB651E688B563F77BA107FB15990C88FB8023386
這是一個例子。
// Some input data
var input = new byte[] { 1, 2, 3 };
// this just works fine
var protectedData = System.Web.Security.MachineKey.Protect(input, "ApplicationCookie", "v1");
// protectedData in hex: A738E5F98920E37AB14C5F4332D4C7F0EC683680AAA0D34B806E75DECF04B7A3DB651E688B563F77BA107FB15990C88FB8023386
// works
var unprotectedInput = System.Web.Security.MachineKey.Unprotect(protectedData, "ApplicationCookie", "v1");
// now lets do it manually
// in web.config machineKey is configured: AES and SHA1
var algorithm = new AesManaged();
algorithm.Padding = PaddingMode.PKCS7;
algorithm.Mode = CipherMode.CBC;
algorithm.KeySize = 256;
algorithm.BlockSize = 128;
var validationAlgorithm = new HMACSHA1();
// this is the key from web.config
var key = HexToBinary("CCA0DC9874B3F9E679E0A576F77EDF9B121CAB2F9A363A4EAF99976F7B51FA89");
using (SymmetricAlgorithm encryptionAlgorithm = algorithm)
{
encryptionAlgorithm.Key = key;
int offset = encryptionAlgorithm.BlockSize / 8; //16
int buffer1Count = validationAlgorithm.HashSize / 8; // 20
int count = checked(protectedData.Length - offset - buffer1Count); // 16
byte[] numArray = new byte[offset];
Buffer.BlockCopy((Array)protectedData, 0, (Array)numArray, 0, numArray.Length);
encryptionAlgorithm.IV = numArray; // in HEX: A738E5F98920E37AB14C5F4332D4C7F0
using (MemoryStream memoryStream = new MemoryStream())
{
using (ICryptoTransform decryptor = encryptionAlgorithm.CreateDecryptor())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(protectedData, offset, count);
// Padding is invalid and cannot be removed.
cryptoStream.FlushFinalBlock();
var result = memoryStream.ToArray();
}
}
}
}
我收到一個異常(填充不正確)。
我不知道還有什么嘗試...
這是MachineKey.Protect的代碼, https: //msdn.microsoft.com/cs-cz/library/system.web.security.machinekey.protect( v = vs.110).aspx
public byte[] Protect(byte[] clearData)
{
// this is AESManaged
using (SymmetricAlgorithm encryptionAlgorithm = this._cryptoAlgorithmFactory.GetEncryptionAlgorithm())
{
// this is our key
encryptionAlgorithm.Key = this._encryptionKey.GetKeyMaterial();
if (this._predictableIV)
encryptionAlgorithm.IV = CryptoUtil.CreatePredictableIV(clearData, encryptionAlgorithm.BlockSize);
else
encryptionAlgorithm.GenerateIV();
byte[] iv = encryptionAlgorithm.IV;
using (MemoryStream memoryStream = new MemoryStream())
{
memoryStream.Write(iv, 0, iv.Length);
using (ICryptoTransform encryptor = encryptionAlgorithm.CreateEncryptor())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream) memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(clearData, 0, clearData.Length);
cryptoStream.FlushFinalBlock();
using (KeyedHashAlgorithm validationAlgorithm = this._cryptoAlgorithmFactory.GetValidationAlgorithm())
{
validationAlgorithm.Key = this._validationKey.GetKeyMaterial();
byte[] hash = validationAlgorithm.ComputeHash(memoryStream.GetBuffer(), 0, checked ((int) memoryStream.Length));
memoryStream.Write(hash, 0, hash.Length);
return memoryStream.ToArray();
}
}
}
}
}
}
解密密鑰錯誤。
MachineKey.Protect / UnProtect()在使用密鑰之前先對其進行修改。
它正在做這樣的事情:
public static byte[] DeriveKey(byte[] key, int keySize, string primaryPurpose, params string[] specificPurposes)
{
var secureUtf8Encoding = new UTF8Encoding(false, true);
var hash = new HMACSHA512(key);
using (hash)
{
var label = secureUtf8Encoding.GetBytes(primaryPurpose);
byte[] context;
using (var memoryStream = new MemoryStream())
{
using (var binaryWriter = new BinaryWriter(memoryStream, secureUtf8Encoding))
{
foreach (var str in specificPurposes)
binaryWriter.Write(str);
context = memoryStream.ToArray();
}
}
return DeriveKeyImpl(hash, label, context, keySize);
}
}
public static byte[] DeriveKeyImpl(HMAC hmac, byte[] label, byte[] context, int keyLengthInBits)
{
int count1 = label != null ? label.Length : 0;
int count2 = context != null ? context.Length : 0;
byte[] buffer = new byte[checked(4 + count1 + 1 + count2 + 4)];
if (count1 != 0)
Buffer.BlockCopy((Array)label, 0, (Array)buffer, 4, count1);
if (count2 != 0)
Buffer.BlockCopy((Array)context, 0, (Array)buffer, checked(5 + count1), count2);
WriteUInt32ToByteArrayBigEndian(checked((uint)keyLengthInBits), buffer, checked(5 + count1 + count2));
int dstOffset = 0;
int val1 = keyLengthInBits / 8;
byte[] numArray = new byte[val1];
uint num = 1;
while (val1 > 0)
{
WriteUInt32ToByteArrayBigEndian(num, buffer, 0);
byte[] hash = hmac.ComputeHash(buffer);
int count3 = Math.Min(val1, hash.Length);
Buffer.BlockCopy((Array)hash, 0, (Array)numArray, dstOffset, count3);
checked { dstOffset += count3; }
checked { val1 -= count3; }
checked { ++num; }
}
return numArray;
}
指定正確的目的非常重要。 對於標准MachineKey.Protect,主要原因是“ User.MachineKey.Protect”。 此示例的密鑰大小為256(以位為單位)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.