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

问题描述

当前,我正在尝试在bouncycastle的帮助下为RSA密钥实现保存功能。如果我尝试将我的公钥或私钥加密后再加载,则会遇到问题。

作为一个小例子,这里是原始公共密钥:

305C300D06092A864886F70D0101010500034B00304802410096B4751049165D1E046063EA22E8FFA0F90AE1DD997A3876DA5F79C7DE97951F009AC9ACA3EB91114F8A32C04F48293B6665CD6DD5C406C81CD13270A2AB61130203010001

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

305C300D06092A864886F70D0101010500034B00304802410096B4751049165D1E046063EA22E8FFA0F90AE1DD997A3876DA5F79C7DE97951F009AC9ACA3EB91114F8A32C04F48293B6665CD6DD5C406C81CD13270A2AB611302030100010000

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

这是我用于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,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,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;
        }
    }

生成密钥对的功能

public static DataBlock[] GenerateKeyPair(KeyPairSize keyPairSize)
        {
            RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
            keyPairGenerator.Init(new KeyGenerationParameters(new SecureRandom(new CryptoApiRandomGenerator()),(int) keyPairSize));
            AsymmetricCipherKeyPair keyPair = keyPairGenerator.GenerateKeyPair();
            PrivateKeyInfo pkInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private);
            SubjectPublicKeyInfo info = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public);
            DataBlock[] keyPairData = new DataBlock[2];
            keyPairData[0] = new DataBlock(pkInfo.GetDerEncoded());
            keyPairData[1] = new DataBlock(info.GetDerEncoded());
            return keyPairData;
        }

重现该错误的代码:

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);

不需要加密/解密方法,因为读取硬盘驱动器上的加密密钥后,该错误已经发生。

为什么/在哪里添加了额外的数据,我该如何解决?

解决方法

我能够通过将密钥的初始字节数组长度添加到加密文本中来修复它,并在以后读取它。在读取功能中,我将所有内容都剪裁成原始大小。

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

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...