Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/262.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我的对称加密将数据添加到我要保存并加载加密的rsa密钥中_C#_Bouncycastle - Fatal编程技术网

C# 我的对称加密将数据添加到我要保存并加载加密的rsa密钥中

C# 我的对称加密将数据添加到我要保存并加载加密的rsa密钥中,c#,bouncycastle,C#,Bouncycastle,目前,我正试图在bouncycastle的帮助下为我的RSA密钥实现一个保存功能。如果我试图保存加密的公钥或私钥并在以后加载它,我会遇到问题 这里举一个小例子,原始公钥: 305C300D06092A864886F70D0101010500034B00304802410096B4751049165D1E046063EA22E8FFA0F90AE1DD997A3876DA5F79C7DE97951F09AC3EB91114F8A32C04F48293B6665CD6DD5C406C81CD1327

目前,我正试图在bouncycastle的帮助下为我的RSA密钥实现一个保存功能。如果我试图保存加密的公钥或私钥并在以后加载它,我会遇到问题

这里举一个小例子,原始公钥:

305C300D06092A864886F70D0101010500034B00304802410096B4751049165D1E046063EA22E8FFA0F90AE1DD997A3876DA5F79C7DE97951F09AC3EB91114F8A32C04F48293B6665CD6DD5C406C81CD13270A2AB611300100001

加载后得到的结果(它添加了4个零,较大的键意味着添加了更多的零):

305C300D06092A864886F70D0101010500034B00304802410096B4751049165D1E046063EA22E8FFA0F90AE1DD997A3876DA5F79C7DE97951F09AC3EB91114F8A32C04F48293B6665CD6DD5C406C81CD13270A2AB6113001000010000

我发现这与我实现的对称加密和使用的填充有关。普通文本无论有多长,都可以正常工作,无需添加额外数据

这是我用于AES加密的代码:

加密

byte[] outputBytes = new byte[0];
AesEngine aesengine = new AesEngine();
CbcBlockCipher aesblockCipher = new CbcBlockCipher(aesengine);
PaddedBufferedBlockCipher aescipher = new PaddedBufferedBlockCipher(aesblockCipher);
KeyParameter aeskeyParameter = new KeyParameter(Hash.HashDataBlock(password, Hash.HashAlgorithm.SHA3).Bytes);
aescipher.Init(true, aeskeyParameter);
outputBytes = new byte[aescipher.GetOutputSize(inputBytes.Bytes.Length)];
int aeslength = aescipher.ProcessBytes(inputBytes.Bytes, outputBytes, 0);
aescipher.DoFinal(outputBytes, aeslength);
解密

byte[] inputBytes = input.Bytes;
byte[] outputBytes = new byte[0];
AesEngine aesengine = new AesEngine();
CbcBlockCipher aesblockCipher = new CbcBlockCipher(aesengine);
PaddedBufferedBlockCipher aescipher = new PaddedBufferedBlockCipher(aesblockCipher);
KeyParameter aeskeyParameter = new KeyParameter(Hash.HashDataBlock(password, Hash.HashAlgorithm.SHA3).Bytes);
aescipher.Init(false, aeskeyParameter);
outputBytes = new byte[aescipher.GetOutputSize(inputBytes.Length)];
int aeslength = aescipher.ProcessBytes(inputBytes, outputBytes, 0);
aescipher.DoFinal(outputBytes, aeslength);
我的功能是保存和加载密钥。DataBlock类只是将数据转换为所需的格式,如UTF8、Base64或字节数组:

public static void SaveKeyEncrypted(DataBlock key, string path, DataBlock password)
{
  StreamWriter sw = new StreamWriter(path);
  DataBlock encrypted = SymmetricEncryption.Encrypt(key, password, SymmetricEncryption.SymmetricAlgorithms.AES);
  sw.Write(encrypted.Base64);
  sw.Close();
}

public static DataBlock ReadKeyEncrypted(string path, DataBlock password)
{
  StreamReader sr = new StreamReader(path);
  DataBlock readData = new DataBlock(sr.ReadLine(), DataBlock.DataType.Base64);
  sr.Close();
  return SymmetricEncryption.Decrypt(readData, password, SymmetricEncryption.SymmetricAlgorithms.AES);
}
为了复制与此问题有关的其他代码:

public class DataBlock
    {
        private byte[] _data;

        public DataBlock()
        {
            this._data = new byte[0];
        }

        public enum DataType
        {
            UTF8,
            UTF7,
            UTF32,
            ASCII,
            Unicode,
            Hex,
            Base64,
            Base32
        }

        public DataBlock(string data, DataType dataType) : this()
        {
            switch (dataType)
            {
                case DataType.UTF8:
                    this._data = Encoding.UTF8.GetBytes(data);
                    break;
                case DataType.UTF7:
                    this._data = Encoding.UTF7.GetBytes(data);  
                    break;
                case DataType.UTF32:
                    this._data = Encoding.UTF32.GetBytes(data);
                    break;
                case DataType.ASCII:
                    this._data = Encoding.ASCII.GetBytes(data);
                    break;
                case DataType.Unicode:
                    this._data = Encoding.Unicode.GetBytes(data);
                    break;
                case DataType.Hex:
                    this._data = new byte[data.Length / 2];
                    for (int i = 0; i < data.Length; i += 2)
                    {
                        this._data[i / 2] = Convert.ToByte(data.Substring(i, 2), 16);
                    }
                    break;
                case DataType.Base64:
                    this._data = Convert.FromBase64String(data);
                    break;
                case DataType.Base32:
                    this._data = this.FromBase32String(data);
                    break;
            }
        }

        public DataBlock(byte[] data)
        {
            this._data = data;
        }

        public string UTF8
        {
            get
            {
                return Encoding.UTF8.GetString(this._data);
            }
        }

        public string UTF7
        {
            get
            {
                return Encoding.UTF7.GetString(this._data);
            }
        }

        public string UTF32
        {
            get
            {
                return Encoding.UTF32.GetString(this._data);
            }
        }

        public string ASCII
        {
            get
            {
                return Encoding.ASCII.GetString(this._data);
            }
        }

        public string Unicode
        {
            get
            {
                return Encoding.Unicode.GetString(this._data);
            }
        }

        public string Hex
        {
            get
            {
                return BitConverter.ToString(this._data).Replace("-", "");
            }
        }

        public string Base64
        {
            get
            {
                return Convert.ToBase64String(this._data);
            }
        }

        public string Base32
        {
            get
            {
                return this.ToBase32String(this._data);
            }
        }

        public byte[] Bytes
        {
            get
            {
                return this._data;
            }
        }

        private string ValidChars = "QAZ2WSX3" + "EDC4RFV5" + "TGB6YHN7" + "UJM8K9LP";

        private string ToBase32String(byte[] bytes)
        {
            StringBuilder sb = new StringBuilder();
            byte index;
            int hi = 5;
            int currentByte = 0;

            while (currentByte < bytes.Length)
            {
                if (hi > 8)
                {
                    index = (byte)(bytes[currentByte++] >> (hi - 5));
                    if (currentByte != bytes.Length)
                    {
                        index = (byte)(((byte)(bytes[currentByte] << (16 - hi)) >> 3) | index);
                    }

                    hi -= 3;
                }
                else if (hi == 8)
                {
                    index = (byte)(bytes[currentByte++] >> 3);
                    hi -= 3;
                }
                else
                {
                    index = (byte)((byte)(bytes[currentByte] << (8 - hi)) >> 3);
                    hi += 5;
                }

                sb.Append(ValidChars[index]);
            }

            return sb.ToString();
        }

        public byte[] FromBase32String(string str)
        {
            int numBytes = str.Length * 5 / 8;
            byte[] bytes = new Byte[numBytes];
            str = str.ToUpper();

            int bit_buffer;
            int currentCharIndex;
            int bits_in_buffer;

            if (str.Length < 3)
            {
                bytes[0] = (byte)(ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5);
                return bytes;
            }

            bit_buffer = (ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5);
            bits_in_buffer = 10;
            currentCharIndex = 2;
            for (int i = 0; i < bytes.Length; i++)
            {
                bytes[i] = (byte)bit_buffer;
                bit_buffer >>= 8;
                bits_in_buffer -= 8;
                while (bits_in_buffer < 8 && currentCharIndex < str.Length)
                {
                    bit_buffer |= ValidChars.IndexOf(str[currentCharIndex++]) << bits_in_buffer;
                    bits_in_buffer += 5;
                }
            }

            return bytes;
        }
    }
复制错误的代码:

DataBlock[] keyPair = AsymmetricEncryption.GenerateKeyPair(AsymmetricEncryption.KeyPairSize.Bits512);
DataBlock pass = new DataBlock("1234", DataBlock.DataType.UTF8);
DataBlock orig = new DataBlock("Hello World", DataBlock.DataType.UTF8);
DataBlock encrypted = AsymmetricEncryption.Encrypt(orig, keyPair[1]);
AsymmetricEncryption.SaveKeyEncrypted(keyPair[0], "D:\\privateenc", pass);
AsymmetricEncryption.SaveKeyEncrypted(keyPair[1], "D:\\publicenc", pass);
DataBlock privateKey = AsymmetricEncryption.ReadKeyEncrypted("D:\\privateenc", pass);
DataBlock publicKey = AsymmetricEncryption.ReadKeyEncrypted("D:\\publicenc", pass);
DataBlock decrypted = AsymmetricEncryption.Decrypt(encrypted, privateKey);
Console.WriteLine(decrypted.UTF8);
不需要加密/解密方法,因为读取硬盘上的加密密钥后已发生错误


为什么/在哪里添加了额外的数据?我如何修复它?

我可以通过将密钥的初始字节数组长度添加到加密文本中并稍后读取来修复它。在read函数中,我在键的原始大小之后剪切所有内容


主要问题仍然存在,这只是一个解决办法。

我能够通过将密钥的初始字节数组长度添加到加密文本中并在以后读取来解决它。在read函数中,我在键的原始大小之后剪切所有内容


主要问题仍然存在,这只是一个解决方法。

这里最好有一些可复制的示例。没有
DataBlock
源代码,我无法复制它。你能让代码示例重现吗?提示:您可以将密钥读/写简化为
DataBlock readData=newdatablock(File.ReadAllText(path),DataBlock.DataType.Base64)
sr
。与
.WriteAllText
相同。我更新了我的问题,以便于复制。这里最好有一些可复制的示例。没有
DataBlock
源代码,我无法复制它。你能让代码示例重现吗?提示:您可以将密钥读/写简化为
DataBlock readData=newdatablock(File.ReadAllText(path),DataBlock.DataType.Base64)
sr
。与
.WriteAllText
相同。我更新了我的问题以便于复制
DataBlock[] keyPair = AsymmetricEncryption.GenerateKeyPair(AsymmetricEncryption.KeyPairSize.Bits512);
DataBlock pass = new DataBlock("1234", DataBlock.DataType.UTF8);
DataBlock orig = new DataBlock("Hello World", DataBlock.DataType.UTF8);
DataBlock encrypted = AsymmetricEncryption.Encrypt(orig, keyPair[1]);
AsymmetricEncryption.SaveKeyEncrypted(keyPair[0], "D:\\privateenc", pass);
AsymmetricEncryption.SaveKeyEncrypted(keyPair[1], "D:\\publicenc", pass);
DataBlock privateKey = AsymmetricEncryption.ReadKeyEncrypted("D:\\privateenc", pass);
DataBlock publicKey = AsymmetricEncryption.ReadKeyEncrypted("D:\\publicenc", pass);
DataBlock decrypted = AsymmetricEncryption.Decrypt(encrypted, privateKey);
Console.WriteLine(decrypted.UTF8);