Base64无效的字符串错误

时间:2013-03-14 20:29:59

标签: c# php encryption base64

我在使用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]);

1 个答案:

答案 0 :(得分: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]);