在VBA中替代.NET的System.Convert

时间:2016-12-10 22:10:03

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

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

目前有以下工作:

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 方法兼容。我不想在加密流中引入额外的字符。
  3. 鉴于我的担忧 - Convert.FromBase64String似乎是最好的选择,因为它保留了.NET中的所有内容,但由于我无法使用它 - 我需要一个替代方案。

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

2 个答案:

答案 0 :(得分:3)

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

您可以在此处找到具有完整Base64编码和解码功能的 VBA / VB6 示例Base64 encoder/decoder in Visual Basic。可以在Base64Coder.bas找到Base64 VB 模块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#OUTPUT

CSharp output

<强> 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输出

enter image description here

答案 1 :(得分:0)

邹,你可能需要这个

使用rsa sha256 sha1 md5 vbscript vba classic asp加密

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