【问题标题】:How do you convert the following encryption code from Perl (or from PHP) to VB.NET?如何将以下加密代码从 Perl(或 PHP)转换为 VB.NET?
【发布时间】:2011-04-27 03:01:00
【问题描述】:

我有一些用 Perl 编写的加密代码(也是 PHP 中的代码 sn-p) - 但我无法获得用 VB.NET 编写的版本来与第三方合作。

Perl 中的示例

    package Sitemaker::API::Crypt;

    use warnings;
    use strict;
    use base qw( Exporter );

    use Crypt::CBC;
    use MIME::Base64;

    our @EXPORT = qw(
        encrypt
        decrypt
    );

    =head2 encrypt( $key, $iv, $arg1[,$arg2][,...]  )

    This encrypts the argumenst (which must all be values, not references) with
    the key (which must be 16 characters long)

    =cut
    sub encrypt {
        my ( $key, $iv, @args ) = @_;
        my $args =  join( '|', @args );

        my $cipher = Crypt::CBC->new(
            -cipher => 'Rijndael',
            -blocksize => 16,
            -keysize => 16,
            -header => 'none',
            -padding => 'standard',
            -iv => $iv,
            -literal_key => 1,
            -key => $key,
        );

        my $binary_token = $cipher->encrypt( $args );

        return encode_base64( $iv . $binary_token );
    }
1;

PHP 中的示例

/**
 * @param string $plaintext
 * @return string encrypted token
 *
 * Relies on the Mcrypt module
 */
 function encrypt( $plaintext, $apiKey)
 {
    // Initialize mcrypt module (AES, 128-bit key, CBC)
    $handle = mcrypt_module_open( MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
    $iv = mcrypt_create_iv( mcrypt_enc_get_iv_size( $handle ), MCRYPT_DEV_URANDOM );

    // PKCS#5 padding
    $blocksize = mcrypt_enc_get_block_size( $handle );
    $padsize = $blocksize - ( strlen( $plaintext ) % $blocksize );
    $plaintext .= str_repeat( chr( $padsize ), $padsize );

    // encrypt
    mcrypt_generic_init( $handle, $apiKey, $iv );
    $ciphertext = mcrypt_generic( $handle, $plaintext );

    // clean up
    mcrypt_generic_deinit( $handle );
    mcrypt_module_close( $handle );

    return base64_encode( $iv. $ciphertext );
}

所以我尝试在 VB.NET 中重新创建相同的内容,但我认为它不起作用,因为我发布到服务并且只是返回错误。 VB.NET中的加密方式是……

 Public Function EncrpytIt(ByVal Key As String, ByVal IV As String, ByVal arrParams As String()) As String
        Dim plainTextBytes As Byte()
        plainTextBytes = Encoding.ASCII.GetBytes(Join(arrParams, "~"))

        Dim outputBytes As Byte()

        Dim symmetricKey As New System.Security.Cryptography.RijndaelManaged()
        With symmetricKey
            .Key = Encoding.ASCII.GetBytes(Key)
            .IV = Encoding.ASCII.GetBytes(IV)
            .Mode = CipherMode.CBC
            .BlockSize = 128 
            .KeySize = 128 
            .Padding = PaddingMode.PKCS7
        End With
        Dim encryptor As ICryptoTransform = symmetricKey.CreateEncryptor(symmetricKey.Key, symmetricKey.IV)
        Using msEncrypt As New MemoryStream()
            Using csEncrypt As New CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)
                csEncrypt.Write(plainTextBytes, 0, plainTextBytes.Length)
                csEncrypt.FlushFinalBlock()
            End Using
            outputBytes = msEncrypt.ToArray
        End Using
        Return IV & Convert.ToBase64String(outputBytes)
    End Function

这是相同的行为方式,还是我必须更改 vb.net 代码中的设置?

【问题讨论】:

    标签: php vb.net perl encryption


    【解决方案1】:

    我看到的第一件事是,在 PHP 和 Perl 的情况下,您使用加密数据对连接的 IV 字符串进行 base 64 编码,而在 VB 中,您返回 IV 的连接字符串和 base 64 编码的输出加密。

    你需要把return语句改成这样:

    Return Convert.ToBase64String(Encoding.ASCII.GetBytes(IV) & outputBytes)
    

    此外,使用的填充方案之间似乎有些不一致 - 至少在 PHP 和 VB.NET 版本之间是这样。基于 PHP 示例中的 cmets - 使用 PKCS #5,而您的 Visual Basic 代码使用 PKCS #7。我不确定在 Perl 的上下文中“标准”是什么意思。

    【讨论】:

    • 这是最后一行的一个非常好的地方。我不知道如何在 vb.net 中获取 PKCS#5 的填充,所以我可能不得不提出另一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 2012-10-17
    • 2011-02-26
    • 1970-01-01
    • 2020-10-02
    • 2011-08-14
    • 1970-01-01
    相关资源
    最近更新 更多