我的对称加密将数据添加到我想要保存和加载加密的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, outputBytes, 0);
aescipher.DoFinal(outputBytes, aeslength);

保存和加载密钥的My Functions。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;
}
}

生成密钥对的功能

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

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

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

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

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

最新更新