为了账号安全,请及时绑定邮箱和手机立即绑定

CSharp 中的加密代码类似于 Go 中的代码(AES、CFB、XorKeyStream)

CSharp 中的加密代码类似于 Go 中的代码(AES、CFB、XorKeyStream)

Go
当年话下 2021-12-20 10:05:26
我在 Go 中有加密代码,但在 CSharp 中很难找到类似的代码。我正在讨论如何实现我自己的 XorKeyStream,但有人告诉我,如果我编写自己的加密代码,则存在法律问题。我相信 CSharp 中一定有类似的代码。package mainimport (    "crypto/aes"    "crypto/cipher"    "fmt")func main() {    k1 := []byte("0123456789abcdef")    r1 := []byte("1234567890abcdef")    data := []byte("0123456789")    fmt.Printf("original %x %s\n", data, string(data))    {        block, _ := aes.NewCipher(k1)        stream := cipher.NewCFBEncrypter(block, r1)        stream.XORKeyStream(data, data)        fmt.Printf("crypted %x\n", data)    }    {        block, _ := aes.NewCipher(k1)        stream := cipher.NewCFBDecrypter(block, r1)        stream.XORKeyStream(data, data)        fmt.Printf("decrypted %x %s\n", data, string(data))    }}http://play.golang.org/p/EnJ56dYX_-输出original 30313233343536373839 0123456789crypted 762b6dcea9c2a7460db7decrypted 30313233343536373839 0123456789PS 有些人将该问题标记为可能与问题重复:“C# AES:加密文件导致“要加密的数据长度无效”。错误”我在 CSharp 中寻找与 Go 中现有代码相同的代码。这个问题是关于填充的。该算法需要将异或文本的“密钥流”。这是不同的问题。
查看完整描述

2 回答

?
PIPIONE

TA贡献1829条经验 获得超9个赞

这是你的代码


using System;

using System.Text;

using System.Security.Cryptography;

using System.IO;


class AES_CFB_XorKeyStream

{

    static void Main(string[] args)

    {

        byte[] data = Encoding.UTF8.GetBytes("0123456789");

        byte [] k1 = Encoding.UTF8.GetBytes("0123456789abcdef");

        byte [] r1 = Encoding.UTF8.GetBytes("1234567890abcdef");


        Console.WriteLine("original " + BitConverter.ToString(data));


        using (RijndaelManaged Aes128 = new RijndaelManaged())

        {

            Aes128.BlockSize = 128;

            Aes128.KeySize = 128;

            Aes128.Mode = CipherMode.CFB;

            Aes128.FeedbackSize = 128;

            Aes128.Padding = PaddingMode.None;

            Aes128.Key = k1;

            Aes128.IV = r1;


            using (var encryptor = Aes128.CreateEncryptor())

            using (var msEncrypt = new MemoryStream())

            using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))

            using (var bw = new BinaryWriter(csEncrypt, Encoding.UTF8))

            {

                bw.Write(data);

                bw.Close();


                data = msEncrypt.ToArray();

                Console.WriteLine("crypted " + BitConverter.ToString(data));

            }

        }


        using (RijndaelManaged Aes128 = new RijndaelManaged())

        {

            Aes128.BlockSize = 128;

            Aes128.KeySize = 128;

            Aes128.Mode = CipherMode.CFB;

            Aes128.FeedbackSize = 128;

            Aes128.Padding = PaddingMode.None;


            Aes128.Key = k1;

            Aes128.IV = r1;


            using (var decryptor = Aes128.CreateDecryptor())

            using (var msEncrypt = new MemoryStream())

            using (var csEncrypt = new CryptoStream(msEncrypt, decryptor, CryptoStreamMode.Write))

            using (var bw = new BinaryWriter(csEncrypt, Encoding.UTF8))

            {

                bw.Write(data);

                bw.Close();


                data = msEncrypt.ToArray();

                Console.WriteLine("decrypted " + BitConverter.ToString(data));

            }

        }

    }

}

输出


original 30-31-32-33-34-35-36-37-38-39

crypted 76-2B-6D-CE-A9-C2-A7-46-0D-B7

decrypted 30-31-32-33-34-35-36-37-38-39


查看完整回答
反对 回复 2021-12-20
?
千万里不及你

TA贡献1784条经验 获得超9个赞

我遇到了完全相同的问题,只有每个解密块的第一个字节是正确的,但我没有能够在 Go 程序上更改源代码的奢侈。


我最终实现了自己的填充。只需用 0 字节填充加密字节,使其可被 128 的块大小整除,然后在运行解密例程后,从末尾切掉该字节数。


示例代码:


using System;

using System.Text;

using System.Security.Cryptography;

using System.Linq;


public static class Program

{

    static RijndaelManaged aes = new RijndaelManaged(){

        Mode = CipherMode.CFB,

        BlockSize = 128,

        KeySize = 128,

        FeedbackSize = 128,

        Padding = PaddingMode.None

    };


    public static void Main(){

        byte[] key = Encoding.UTF8.GetBytes("0123456789abcdef");

        byte[] iv = Encoding.UTF8.GetBytes("1234567890abcdef");

        byte[] encryptedBytes = new byte[]{0x76, 0x2b, 0x6d, 0xce, 0xa9, 0xc2, 0xa7, 0x46, 0x0d, 0xb7};


        // Custom pad the bytes

        int padded;

        encryptedBytes = PadBytes(encryptedBytes, aes.BlockSize, out padded);


        // Decrypt bytes

        byte[] decryptedBytes = DecryptBytesAES(encryptedBytes, key, iv, encryptedBytes.Length);


        // Check for successful decrypt

        if(decryptedBytes != null){

            // Unpad

            decryptedBytes = UnpadBytes(decryptedBytes, padded);

            Console.Write("Decrypted: " + Encoding.UTF8.GetString(decryptedBytes));

        }


    }


    // Just an elegant way of initializing an array with bytes

    public static byte[] Initialize(this byte[] array, byte value, int length)

    {

        for (int i = 0; i < array.Length; i++)

        {

            array[i] = value;

        }

        return array;

    }


    // Custom padding to get around the issue of how Go uses CFB mode without padding differently than C#

    public static byte[] PadBytes(byte[] encryptedBytes, int blockSize, out int numPadded)

    {

        numPadded = 0;


        // Check modulus of block size

        int mod = encryptedBytes.Length % blockSize;

        if (mod != 0)

        {

            // Calculate number to pad

            numPadded = blockSize - mod;


            // Build array

            return encryptedBytes.Concat(new byte[numPadded].Initialize(0, numPadded)).ToArray();

        }

        else {

            // No padding needed

            return encryptedBytes;

        }

    }

    public static byte[] UnpadBytes(byte[] decryptedBytes, int numPadded)

    {

        if(numPadded != 0)

        {

            byte[] unpaddedBytes = new byte[decryptedBytes.Length - numPadded];

            Array.Copy(decryptedBytes, unpaddedBytes, unpaddedBytes.Length);

            return unpaddedBytes;

        }

        else

        {

            return decryptedBytes;

        }

    }


    public static byte[] DecryptBytesAES(byte[] cipherText, byte[] Key, byte[] IV, int size)

    {

        byte[] array = new byte[size];

        try{

            aes.Key = Key;

            aes.IV = IV;

            ICryptoTransform transform = aes.CreateDecryptor(aes.Key, aes.IV);

            using (System.IO.MemoryStream memoryStream = new System.IO.MemoryStream(cipherText))

            {

                using (CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read))

                {

                    cryptoStream.Read(array, 0, size);

                }

            }

        }

        catch(Exception e){

            return null;

        }

        return array;

    }

}

.NET 小提琴:https : //dotnetfiddle.net/NPHKN3


查看完整回答
反对 回复 2021-12-20
  • 2 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信