0

我在 C# 中使用 Base64 字符串时遇到问题

我有一个从 php 调用的 .exe。它获取 2 个参数并返回一个加密密钥。(.exe 是我遇到问题的地方)

在php中我这样做:

<?php
$key = "AAAA";
$pass=" AAAA";
echo shell_exec("cryptograph.exe generateKey $key $pass");
?>

它应该可以工作,因为它们是 64 进制字符串,或者至少,我知道长度为 4 的倍数的字符串是有效的 64 进制字符串。

但我得到以下信息(是西班牙语,但我会在下面翻译):

Encrypt en System.Convert.FromBase64String(String s) 
en cryptograph.Cryptography.Encrypt(String plainStr, String completeEncodedKey, Int32 keySize) en cryptograph.Cryptography.generateKey(String key, String pass) 
en cryptograph.cryptograph.Main(String[] args) 
La entrada no es una cadena Base 64 v lida porque contiene un car cter que no es Base 64, m s de dos caracteres de relleno o un car cter de relleno que no es un espacio en blanco

基本上它说它不是有效的 Base64 字符串,因为它包含一个不是 Base 65 的字符,而不是填充符(relleno 是这样翻译的?)字符,它们不是空格。

这是 c# 代码的一部分。

    public static void generateKey(String key, String pass)
    {
        String e = Encrypt(pass, key, 256);
        Console.WriteLine("Entro generateKey");
        System.Console.WriteLine(e);
    }

    private static string Encrypt(string plainStr, string completeEncodedKey, int keySize)
    {
        Console.WriteLine("Entro Encrypt");
        RijndaelManaged aesEncryption = new RijndaelManaged();
        aesEncryption.KeySize = keySize;
        aesEncryption.BlockSize = 128;
        aesEncryption.Mode = CipherMode.CBC;
        aesEncryption.Padding = PaddingMode.PKCS7;
        Console.WriteLine(completeEncodedKey);
        aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
        aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]);
        byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr);
        ICryptoTransform crypto = aesEncryption.CreateEncryptor();
        Console.WriteLine("Abajo de crypto");
        // The result of the encryption and decryption            
        byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length);
        return Convert.ToBase64String(cipherText);
    }

问题发生在以下两行中的一些行中:

aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);
aesEncryption.Key = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString(Convert.FromBase64String(completeEncodedKey)).Split(',')[1]);
4

1 回答 1

2

首先,真的不清楚completeEncodedKey真正代表什么。如果它是用于返回加密密钥的 cryptograph.exe 的结果,那么您肯定需要解密它 - 这不是您在这里实际做的事情。

无论如何,我确定这是问题所在(两次,一次用于 IV,一次用于密钥):

aesEncryption.IV = Convert.FromBase64String(ASCIIEncoding.UTF8.GetString
    (Convert.FromBase64String(completeEncodedKey)).Split(',')[0]);

为了理智,让我们将其拆分一下:

byte[] completeBinaryKey = Convert.FromBase64String(completeEncodedKey);
string asciiKey = ASCIIEncoding.UTF8.GetString(completeBinaryKey);
string[] parts = asciiKey.Split(',');
string ivBase64 = parts[0];
aesEncryption.IV = Convert.FromBase64String(ivBase64);

一开始,ASCIIEncoding.UTF8是极其混乱的。如果您真的只想要 UTF-8,为什么还要将 ASCII 加入其中?您应该使用Encoding.UTF8更清晰。但是,我认为您根本不想要这个。

为什么要从 base64 转换两次?如果“整体”值是 UTF-8 编码的文本,为什么要转换为 base64?

我强烈怀疑您的文字实际上是以下形式:

<base64-encoded-iv>,<base64-encoded-key>

在这种情况下,您只需将其拆分base64 转换:

string[] parts = completeEncodedKey.Split(',');
aesEncryption.IV = Convert.FromBase64String(parts[0]);
aesEncryption.Key = Convert.FromBase64String(parts[1]);
于 2013-03-14T20:39:48.857 回答