如何申请用于填充的Base64 [英] How to apply padding for Base64

查看:135
本文介绍了如何申请用于填充的Base64的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下code当我用四个字母组成的单词作为输入的正常工作,例如: 测试。当输入不是4的倍数时,它失败例如MyTest的。

  

Eexception:无效的长度为一个base-64字符数组

问题

  1. 在能够保证所有的加密结果将永远兼容一个统一code字符串(没有任何损失)。如果是的话,我可以使用UTF编码,而不是Base64的? <一href="http://stackoverflow.com/questions/3866316/whats-the-difference-between-utf8-utf16-and-base64-in-terms-of-encoding">What's在编码方面UTF8 / UTF16和Base64的之间的区别
  2. 如何添加填料使我们得到正确的结果(解密后的),即使输入不是4的倍数?

主要PRGORAM

 类节目
{
    静态无效的主要(字串[] args)
    {
        字符串valid128BitString =AAECAwQFBgcICQoLDA0ODw ==;
        字符串inputValue将=MyTest的;
        字符串的keyValue = valid128BitString;


        byte []的byteValForString = Convert.FromBase64String(inputValue将);
        EncryptResult结果= Aes128Utility.EncryptData(byteValForString,的keyValue);
        EncryptResult encyptedValue =新EncryptResult();
        字符串resultingIV =4uy34C9sqOC9rbV4GD8jrA ==;
        如果(String.Equals(resultingIV,result.IV))
        {
            INT X = 0;
        }

        encyptedValue.IV = resultingIV;
        encyptedValue.EncryptedMsg = result.EncryptedMsg;

        字符串finalResult = Convert.ToBase64String(Aes128Utility.DecryptData(encyptedValue,的keyValue));
        Console.WriteLine(finalResult);

        如果(String.Equals(inputValue将,finalResult))
        {
            Console.WriteLine(匹配);
        }
        其他
        {
            Console.WriteLine(不同);
        }

        到Console.ReadLine();
    }
}
 

AES加密UTILITY

 公共静态类Aes128Utility
{
    私人静态字节[]键;

    公共静态EncryptResult EncryptData(byte []的RAWDATA,串strKey)
    {
        EncryptResult结果= NULL;
        如果(关键== NULL)
        {
            如果(!String.IsNullOrEmpty(strKey))
            {
                键= Convert.FromBase64String((strKey));
                结果=加密(RAWDATA);
            }
        }
        其他
        {
            结果=加密(RAWDATA);
        }

        返回结果;

    }

    公共静态的byte [] DecryptData(EncryptResult encryptResult,串strKey)
    {
        byte []的origData = NULL;
        如果(关键== NULL)
        {
            如果(!String.IsNullOrEmpty(strKey))
            {
                键= Convert.FromBase64String(strKey);
                origData =解密(Convert.FromBase64String(encryptResult.EncryptedMsg),Convert.FromBase64String(encryptResult.IV));
            }
        }
        其他
        {
            origData =解密(Convert.FromBase64String(encryptResult.EncryptedMsg),Convert.FromBase64String(encryptResult.IV));
        }

        返回origData;
    }

    私有静态EncryptResult加密(byte []的RAWDATA)
    {
        使用(AesCryptoServiceProvider aesProvider =新AesCryptoServiceProvider())
        {
            aesProvider.Key =键;
            aesProvider.Mode = CipherMode.CBC;
            aesProvider.Padding = PaddingMode.PKCS7;
            aesProvider.IV = Convert.FromBase64String(4uy34C9sqOC9rbV4GD8jrA ==);
            使用(MemoryStream的memStream =新的MemoryStream())
            {
                CryptoStream的encStream =新的CryptoStream(memStream,aesProvider.CreateEncryptor(),CryptoStreamMode.Write);
                encStream.Write(RAWDATA,0,rawData.Length);
                encStream.FlushFinalBlock();
                EncryptResult encResult =新EncryptResult();
                encResult.EncryptedMsg = Convert.ToBase64String(memStream.ToArray());
                encResult.IV = Convert.ToBase64String(aesProvider.IV);
                返回encResult;
            }
        }
    }

    私有静态的byte []解密(byte []的encryptedMsg,字节[] IV)
    {
        使用(AesCryptoServiceProvider aesProvider =新AesCryptoServiceProvider())
        {
            aesProvider.Key =键;
            aesProvider.IV = IV;
            aesProvider.Mode = CipherMode.CBC;
            aesProvider.Padding = PaddingMode.PKCS7;
            使用(MemoryStream的memStream =新的MemoryStream())
            {
                CryptoStream的decStream =新的CryptoStream(memStream,aesProvider.CreateDecryptor(),CryptoStreamMode.Write);
                decStream.Write(encryptedMsg,0,encryptedMsg.Length);
                decStream.FlushFinalBlock();
                返回memStream.ToArray();
            }
        }
    }

 }
 

DTO

 公共类EncryptResult
{
    公共字符串EncryptedMsg {获得;组; }
    公共字符串IV {获得;组; }
}
 

参考

  1. <一个href="http://stackoverflow.com/questions/14954248/how-to-create-byte-with-length-16-using-frombase64string">How创建byte []的长度为16使用FromBase64String
  2. <一个href="http://stackoverflow.com/questions/14937707/getting-incorrect-decryption-value-using-aescryptoserviceprovider">Getting使用AesCryptoServiceProvider
  3. 不正确解密值
解决方案

Base64的是重新presenting二进制值的方式为文本,这样你就不会与同一控制codeS像 \ X0A 为新行或 \ 0 为一个字符串结束。这是不会作为转动输入文字的二进制。

下面是你应该如何传递文本,并得到它退了出去。您可以替换 UTF8 与任何编码,你想要的,但你需要确保 Encoding.Whatever.GetBytes 是相同的编码为 Encoding.Whatever.GetString

 类节目
{
    静态无效的主要(字串[] args)
    {
        字符串valid128BitString =AAECAwQFBgcICQoLDA0ODw ==;
        字符串inputValue将=MyTest的;
        字符串的keyValue = valid128BitString;

        //打开我们的文字中二进制数据
        byte []的byteValForString = Encoding.UTF8.GetBytes(inputValue将);

        EncryptResult结果= Aes128Utility.EncryptData(byteValForString,的keyValue);
        EncryptResult encyptedValue =新EncryptResult();

        //(剪断)

        encyptedValue.IV = resultingIV;
        encyptedValue.EncryptedMsg = result.EncryptedMsg;

        字符串finalResult = Encoding.UTF8.GetString(Aes128Utility.DecryptData(encyptedValue,的keyValue));
        Console.WriteLine(finalResult);

        如果(String.Equals(inputValue将,finalResult))
        {
            Console.WriteLine(匹配);
        }
        其他
        {
            Console.WriteLine(不同);
        }

        到Console.ReadLine();
    }
}
 

I have following code that works fine when I use a four letter word as input, E.g. "Test". When the input is not a multiple of 4, it fails E.g. "MyTest".

Eexception: Invalid length for a Base-64 char array.

QUESTIONS

  1. Is it guaranteed that the encrypted result will be always compatible to a Unicode string (without any loss). If yes I can use UTF encoding instead of Base64? What's the difference between UTF8/UTF16 and Base64 in terms of encoding
  2. How can add padding so that we get correct result (after decryption) even if the input is not a multiple of 4?

MAIN PRGORAM

class Program
{
    static void Main(string[] args)
    {
        string valid128BitString = "AAECAwQFBgcICQoLDA0ODw==";
        string inputValue = "MyTest";
        string keyValue = valid128BitString;


        byte[] byteValForString = Convert.FromBase64String(inputValue);
        EncryptResult result = Aes128Utility.EncryptData(byteValForString, keyValue);
        EncryptResult encyptedValue = new EncryptResult();
        string resultingIV = "4uy34C9sqOC9rbV4GD8jrA==";
        if (String.Equals(resultingIV,result.IV))
        {
            int x = 0;
        }

        encyptedValue.IV = resultingIV;
        encyptedValue.EncryptedMsg = result.EncryptedMsg;

        string finalResult = Convert.ToBase64String(Aes128Utility.DecryptData(encyptedValue, keyValue));
        Console.WriteLine(finalResult);

        if (String.Equals(inputValue, finalResult))
        {
            Console.WriteLine("Match");
        }
        else
        {
            Console.WriteLine("Differ");
        }

        Console.ReadLine();
    }
}

AES Crypto UTILITY

public static class Aes128Utility
{
    private static byte[] key;

    public static EncryptResult EncryptData(byte[] rawData, string strKey)
    {
        EncryptResult result = null;
        if (key == null)
        {
            if (!String.IsNullOrEmpty(strKey))
            {
                key = Convert.FromBase64String((strKey));
                result = Encrypt(rawData);
            }
        }
        else
        {
            result = Encrypt(rawData);
        }

        return result; 

    }

    public static byte[] DecryptData(EncryptResult encryptResult, string strKey)
    {
        byte[] origData = null;
        if (key == null)
        {
            if (!String.IsNullOrEmpty(strKey))
            {
                key = Convert.FromBase64String(strKey);
                origData = Decrypt(Convert.FromBase64String(encryptResult.EncryptedMsg), Convert.FromBase64String(encryptResult.IV));
            }
        }
        else
        {
            origData = Decrypt(Convert.FromBase64String(encryptResult.EncryptedMsg), Convert.FromBase64String(encryptResult.IV));
        }

        return origData; 
    }

    private static EncryptResult Encrypt(byte[] rawData)
    {
        using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
        {
            aesProvider.Key = key;
            aesProvider.Mode = CipherMode.CBC;
            aesProvider.Padding = PaddingMode.PKCS7;
            aesProvider.IV = Convert.FromBase64String("4uy34C9sqOC9rbV4GD8jrA==");
            using (MemoryStream memStream = new MemoryStream())
            {
                CryptoStream encStream = new CryptoStream(memStream, aesProvider.CreateEncryptor(), CryptoStreamMode.Write);
                encStream.Write(rawData, 0, rawData.Length);
                encStream.FlushFinalBlock();
                EncryptResult encResult = new EncryptResult();
                encResult.EncryptedMsg = Convert.ToBase64String(memStream.ToArray());
                encResult.IV = Convert.ToBase64String(aesProvider.IV);
                return encResult;
            }
        }
    }

    private static byte[] Decrypt(byte[] encryptedMsg, byte[] iv)
    {
        using (AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider())
        {
            aesProvider.Key = key;
            aesProvider.IV = iv;
            aesProvider.Mode = CipherMode.CBC;
            aesProvider.Padding = PaddingMode.PKCS7;
            using (MemoryStream memStream = new MemoryStream())
            {
                CryptoStream decStream = new CryptoStream(memStream, aesProvider.CreateDecryptor(), CryptoStreamMode.Write);
                decStream.Write(encryptedMsg, 0, encryptedMsg.Length);
                decStream.FlushFinalBlock();
                return memStream.ToArray();
            }
        }
    }

 }

DTO

public class EncryptResult
{
    public string EncryptedMsg { get; set; }
    public string IV { get; set; }
}

REFERENCES:

  1. How to create byte[] with length 16 using FromBase64String
  2. Getting incorrect decryption value using AesCryptoServiceProvider

解决方案

Base64 is a way of representing binary values as text so that you do not conflict with common control codes like \x0A for newline or \0 for a string terminator. It is NOT for turning typed text in to binary.

Here is how you should be passing the text in and getting it back out. You can replace UTF8 with whatever encoding you want, but you will need to make sure the Encoding.Whatever.GetBytes is the same encoding as the Encoding.Whatever.GetString

class Program
{
    static void Main(string[] args)
    {
        string valid128BitString = "AAECAwQFBgcICQoLDA0ODw==";
        string inputValue = "MyTest";
        string keyValue = valid128BitString;

        //Turns our text in to binary data
        byte[] byteValForString = Encoding.UTF8.GetBytes(inputValue);

        EncryptResult result = Aes128Utility.EncryptData(byteValForString, keyValue);
        EncryptResult encyptedValue = new EncryptResult();

        //(Snip)

        encyptedValue.IV = resultingIV;
        encyptedValue.EncryptedMsg = result.EncryptedMsg;

        string finalResult = Encoding.UTF8.GetString(Aes128Utility.DecryptData(encyptedValue, keyValue));
        Console.WriteLine(finalResult);

        if (String.Equals(inputValue, finalResult))
        {
            Console.WriteLine("Match");
        }
        else
        {
            Console.WriteLine("Differ");
        }

        Console.ReadLine();
    }
}

这篇关于如何申请用于填充的Base64的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆