【问题标题】:Alternative for .NET's System.Convert within VBAVBA 中 .NET 的 System.Convert 的替代方案
【发布时间】:2017-04-26 03:18:12
【问题描述】:

我正在 Microsoft Access 中编写一个 VBA 函数,以使用 RSA 密钥加密/解密文本数据。

目前有以下作品:

CreateObject("System.Security.Cryptography.RSACryptoServiceProvider")
CreateObject("System.Text.UTF8Encoding")

但这不起作用:

CreateObject("System.Convert")

我做了一些研究,发现了这个 stackoverflow 问题: Can I call a static method of a C# class from VBA via COM?

事实证明,System.Convert 是一个静态类,因此它对 COM 对象不可用,因此对 VBA 也不可用。

我可以将我所有的 .NET 内容包装到我自己的类中,然后将其添加到 Access 作为参考,但这有点超出我的舒适范围,我宁愿不必为此维护自定义参考项目。

因此,我没有专注于 System.Convert 选项,而是考虑了我的具体需求。我需要能够:

  • 将 Base 64 编码字符串转换为字节数组并传递给 .NET 方法
  • 将从 .NET 调用返回的字节数组转换为 Base 64 编码字符串

我看到的最简单的选择是编写自己的 VBA 代码来在 Base 64 和字节数组之间进行转换 - 但是我发现了两个陷阱:

  1. 编码问题。在字节数组和字符串之间进行转换意味着必须处理编码问题。
  2. Base64 变体。在我的脑海中,Base64 中可能包含 CR/LF。我也不确定 Base64 编码的 RSA 字符串是否有/需要有一个标题。如果我编写自己的 Base64 函数,我需要确保它与 RSACryptoServiceProvider 的 FromBase64String 方法兼容。我不想在加密流中引入额外的字符。

考虑到我的担忧 - Convert.FromBase64String 似乎是最佳选择,因为它将所有内容都保存在 .NET 中,但由于我不能使用它 - 我需要一个替代方案。

如果有其他提供 FromBase64String 和 ToBase64String 功能但能够通过 CreateObject 实例化的标准 .NET 类 - 这可能是最佳选择。但是我不知道。

【问题讨论】:

  • .NET 是 Windows API 的包装器。系统 COM 库也是 Windows API 的包装器。有一个 COM 接口 (CAPICOM),但它只有 32 位。而是使用 API 调用 msdn.microsoft.com/en-us/library/windows/desktop/…
  • 我从未意识到这一点——但我也从未真正考虑过。我猜是因为我认为它是不同的所有 CLR 东西。这很有帮助。

标签: .net vba ms-access com com-interop


【解决方案1】:

有许多 VBA/VBScript/VB6 Base64 实现与 .NET ToBase64String 用于编码和FromBase64String 用于解码产生完全相同的结果。

您可以在此处Base64 encoder/decoder in Visual Basic 找到具有完整 Base64 编码和解码功能的 VBA/VB6 示例。 Base64 VB 模块的 bas 文件可以在这里找到Base64Coder.bas

以下是C#VB6 中相同测试的一些屏幕截图。您可以清楚地看到两种语言的结果是相同的:

C#

static void Main(string[] args)
{
    Check("Aladdin:open sesame", "QWxhZGRpbjpvcGVuIHNlc2FtZQ=="); // example from RFC 2617)
    Check("1", "MQ==");
    Check("22", "MjI=");
    Check("333", "MzMz");
    Check("4444", "NDQ0NA==");
    Check("55555", "NTU1NTU=");
    Check("abc:def", "YWJjOmRlZg==");
    Check("????", "Pz8/Pw==");
    Check("abcdefghijklnmopqrstuvwxyz0123456789???", "YWJjZGVmZ2hpamtsbm1vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Pz8/");
}

private static void Check(string plainText, string base64Text)
{
    string s1 = Base64Encode(plainText);
    string s2 = Base64Decode(base64Text);

    Debug.WriteLine("String: " + s2 + ", to Base64: " + s1);

    if(s1 != base64Text || s2 != plainText)
        Debug.WriteLine("Check failed for \"" + plainText + "\" / \"" + base64Text + "\".");
}
public static string Base64Encode(string plainText)
{
    var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
    return System.Convert.ToBase64String(plainTextBytes);
}

public static string Base64Decode(string base64EncodedData)
{
    var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
    return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}

C# 输出

VBA/VB6

Public Sub Main()
    Check "Aladdin:open sesame", "QWxhZGRpbjpvcGVuIHNlc2FtZQ==" ' example from RFC 2617
    Check "1", "MQ=="
    Check "22", "MjI="
    Check "333", "MzMz"
    Check "4444", "NDQ0NA=="
    Check "55555", "NTU1NTU="
    Check "abc:def", "YWJjOmRlZg=="
    Check "????", "Pz8/Pw=="
    Check "abcdefghijklnmopqrstuvwxyz0123456789???", "YWJjZGVmZ2hpamtsbm1vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Pz8/"
End Sub

Private Sub Check(ByVal plainText As String, ByVal base64Text As String)
    Dim s1 As String: s1 = Base64EncodeString(plainText)
    Dim s2 As String: s2 = Base64DecodeString(base64Text)

    Debug.Print "String: " & s2 & ", Base64: " & s1

    If s1 <> base64Text Or s2 <> plainText Then _
        Debug.Print "Check failed for """ & plainText & """ / """ & base64Text & """."
End Sub

VBA/VB6 输出

【讨论】:

    【解决方案2】:

    你可能需要这个

    用 rsa sha256 sha1 md5 vbscript vba 经典 asp 加密

    https://github.com/ekede/WTS-Classic-ASP-MVC-Framework/blob/master/inc/class/crypt/rsa.asp

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多