gpt4 book ai didi

c# - 将 advapi32.dll 加密调用转换为 .NET

转载 作者:行者123 更新时间:2023-12-05 03:16:40 27 4
gpt4 key购买 nike

我需要将数据从遗留系统传输到新的第 3 方系统。

一些数据是加密的,我需要为新系统解密它,新系统将拥有自己的现代加密。

遗留解密代码是用 VB6 编写的。我正在尝试将其转换为 .NET 代码,但我很难让它工作。

旧的、简化的代码是这样的:

'Const ENCRYPT_BLOCK_SIZE as Integer = 8

Dim hCSP As Long
Dim strContexte As String
Dim Password as String
Dim lngPassword as Long
Dim strEncrypted as String
Dim lngEncrypted as Long
Dim strBuffer as String
Dim lngBuffer as Long
Dim hHash as Long
Dim lngRC as Long

strContexte = "Some Context"
Password = "SomeString"
lngPassword = Len(Password)

strEncrypted = "String to decrypt"
lngEncrypted = Len(strEncrypted)
lngBuffer = lngEncrypted + ENCRYPT_BLOCK_SIZE
LSet strBuffer = strEncrypted


lngRC = CryptAcquireContext(hCSP, strContext, "Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_MACHINE_KEYSET)
If Not CBool(lngRC) Then
If Err.LastDllError = NTE_BAD_KEYSET Then
lngRC = CryptAcquireContext(hCSP, strContext, "Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_NEWKEYSET + CRYPT_MACHINE_KEYSET)
End If

lngRC = CryptCreateHash(hCSP, CALG_SHA1, 0, 0, hHash)
lngRC = CryptHashData(hHash, Password, lngPassword, 0)
lngRC = CryptDeriveKey(hCSP, CALG_RC4, hHash, 0, hHash)
lngRC = CryptDecrypt(hHash, 0, 1, 0, strBuffer, lngBuffer)

由于此代码片段是在登录时比较密码的代码的一部分,因此不易访问,并且在旧服务器上运行。

所以我尝试使用更新的代码重现解密,以便我可以在 ETL session 期间调用它。

我的 C# 代码如下所示:

        string Password = "SomeString";
string info = "String to decrypt";
byte[] value = Convert.ToByte(info, 16)

long lngInfo = info.Length;
long lngBuffer = lngInfo + 8;
byte[] Buffer = new byte[lngBuffer];

value.CopyTo(Buffer, 0);


byte[] key;
using (PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password, null))
{
key = pdb.CryptDeriveKey("TripleDES", "SHA1", 0, new byte[8]);
}


byte[] decrypted;
using (var prov = new TripleDESCryptoServiceProvider())
{
using (var decryptor = prov.CreateDecryptor(key, new byte[8]))
{
decrypted = decryptor.TransformFinalBlock(Buffer, 0, lngBuffer);
}
}

我完全不了解这段代码,运行它时出现错误:

System.Security.Cryptography.CryptographicException: 'Length of thedata to decrypt is invalid.'

旧代码有 PROV_RSA_FULL、SHA1 和 RC4,我如何在新代码中插入 RC4?

较新的环境是:Windows 2016

我知道密码可能会导致问题,但首先我想修复 .net 代码,稍后我会专注于其他问题!

感谢您的帮助!

最佳答案

好吧,因为这是一次性的工作而不是永久的解决方案,所以我最终做的是在我的 C# 代码中重现相同的 Win32 api 调用。

在对字节数组和值进行一些调整后,它可以完美地工作。

我最开心的是关键建筑,但那是另一个话题。

所以首先我创建了一个小类来封装所有 DLL 导入:

public static class ADVAPI32
{
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CryptAcquireContext(out IntPtr hProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CryptHashData(IntPtr hHash, byte[] pbData, uint dataLen, uint flags);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CryptCreateHash(IntPtr hProv, uint algId, IntPtr hKey, uint dwFlags, ref IntPtr phHash);
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDeriveKey(IntPtr hProv, int Algid, IntPtr hBaseData, int flags, ref IntPtr phKey);

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptDecrypt(IntPtr hKey, IntPtr hHash, int Final, uint dwFlags, byte[] pbData, ref uint pdwDataLen);

[DllImport("Advapi32.dll", EntryPoint = "CryptReleaseContext", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CryptReleaseContext(IntPtr hProv, int dwFlags);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CryptDestroyHash(IntPtr hHash);

public static string GetAPIErrorMessageDescription()
{
return new Win32Exception(Marshal.GetLastWin32Error()).Message;
}
}

在主类中,创建了几个常量:

    byte[] Pass { get; set; }
static readonly string Context = "Context";
static readonly string Name_CSP = "Microsoft Base Cryptographic Provider v1.0";

const uint PROV_RSA_FULL = 1;
const uint CRYPT_MACHINE_KEYSET = 0x20;

const int ALG_CLASS_DATA_ENCRYPT = 0x6000;
const int ALG_CLASS_HASH = 0x8000;
const int ALG_TYPE_ANY = 0;
const int ALG_TYPE_STREAM = 0x800;

const int ALG_SID_RC4 = 1;
const int ALG_SID_SHA1 = 4;

const int CALG_RC4 = ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_STREAM | ALG_SID_RC4;
const int CALG_SHA1 = ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA1;

以及解密方法:

public string Decrypt(byte[] info)
{
IntPtr href = IntPtr.Zero;
IntPtr hCSP = IntPtr.Zero;

try
{

var success = ADVAPI32.CryptAcquireContext(out hCSP, Context, NAME_CSP, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET);
if (!success)
{
throw new ApplicationException("Error with CryptAcquireContext: " + ADVAPI32.GetAPIErrorMessageDescription());
}

success = ADVAPI32.CryptCreateHash(hCSP, CALG_SHA1, IntPtr.Zero, 0, ref href);
if (!success)
{
throw new ApplicationException("Error with CryptCreateHash: " + ADVAPI32.GetAPIErrorMessageDescription());
}

var dataLength = Convert.ToUInt32(Pass.Length);

success = ADVAPI32.CryptHashData(href, MDP, dataLength, 0);
if (!success)
{
throw new ApplicationException("Error with CryptHashData: " + ADVAPI32.GetAPIErrorMessageDescription());
}

success = ADVAPI32.CryptDeriveKey(hCSP, CALG_RC4, href, 0, ref href);
if (!success)
{
throw new ApplicationException("Error with CryptDeriveKey: " + ADVAPI32.GetAPIErrorMessageDescription());
}

var bufferLen = Convert.ToUInt32(info.Length);

success = ADVAPI32.CryptDecrypt(href, IntPtr.Zero, 1, 0, info, ref bufferLen);
if (!success)
{
throw new ApplicationException("Error with CryptDecrypt: " + ADVAPI32.GetAPIErrorMessageDescription());
}

var strTxt = Encoding.ASCII.GetString(info, 0, Convert.ToInt32(bufferLen));
strTxt = strTxt.Substring(0, strTxt.Length / 2 - 4);

return strTxt;
}
finally
{
if (href != IntPtr.Zero)
{
ADVAPI32.CryptDestroyHash(href);
}
if (hCSP != IntPtr.Zero)
{
ADVAPI32.CryptReleaseContext(hCSP, 0);
}
}
}

感谢 jdweng 的想法。

关于c# - 将 advapi32.dll 加密调用转换为 .NET,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74567216/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com