我有一个名为Stegolayer()
的LSB隐写函数,我向其发送要隐藏的数据。我的原始数据使用AES加密,并保存到output
。与此同时,我附加文件字节哈希码和会话密钥,用RSA加密。
实际上,我的嵌入式秘密包括加密数据+哈希码&会话密钥作为一个单字节流。提取后,我该如何拆分这两部分?
我按如下方式构建bytestobehidden
EncryptFile(pass_txt.Text, loadedFilePath, output);
fileContainer = File.ReadAllBytes(output);
hashcode = SHA256.Create().ComputeHash(File.ReadAllBytes(loadedFilePath));
Newpassword = CreateRandomPassword(pass_txt.Text.Length);
Newpasswordbytes = Byteconverter.GetBytes(Newpassword);
RSAplain= Combine(hashcode,Newpasswordbytes);
RSAcipher = RSAencryption(RSAplain, RSA.ExportParameters(false), false);
bytestobehidden = Combine(fileContainer, RSAcipher);
fileSize = bytestobehidden.Length;
if (8 * ((height * (width / 3) * 3) / 3 - 1) < fileSize + fileNameSize)
{
MessageBox.Show("File size is too large!\nPlease use a larger image to hide this file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
StegoLayer();
private byte[] Combine(byte[] a, byte[] b)
{
byte[] c = new byte[a.Length + b.Length];
System.Buffer.BlockCopy(a, 0, c, 0, a.Length);
System.Buffer.BlockCopy(b, 0, c, a.Length, b.Length);
return c;
}
public static void EncryptFile(string password, string in_file, string out_file)
{
CryptFile(password, in_file, out_file, true);
}
public static void DecryptFile(string password, string in_file, string out_file)
{
CryptFile(password, in_file, out_file, false);
}
public static void CryptFile(string password,string in_file, string out_file, bool encrypt)
{
// Create input and output file streams.
using (FileStream in_stream =
new FileStream(in_file, FileMode.Open, FileAccess.Read))
{
using (FileStream out_stream =
new FileStream(out_file, FileMode.Create,
FileAccess.Write))
{
// Encrypt/decrypt the input stream into
// the output stream.
CryptStream(password, in_stream, out_stream, encrypt);
}
}
}
// Encrypt the data in the input stream into the output stream.
public static void CryptStream(string password,
Stream in_stream, Stream out_stream, bool encrypt)
{
// Make an AES service provider.
AesCryptoServiceProvider aes_provider =
new AesCryptoServiceProvider();
// Find a valid key size for this provider.
int key_size_bits = 0;
for (int i = 1024; i > 1; i--)
{
if (aes_provider.ValidKeySize(i))
{
key_size_bits = i;
break;
}
}
//Debug.Assert(key_size_bits > 0);
// Console.WriteLine("Key size: " + key_size_bits);
// Get the block size for this provider.
int block_size_bits = aes_provider.BlockSize;
// Generate the key and initialization vector.
byte[] key = null;
byte[] iv = null;
byte[] salt = { 0x0, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,
0xF1, 0xF0, 0xEE, 0x21, 0x22, 0x45 };
MakeKeyAndIV(password, salt, key_size_bits, block_size_bits,
out key, out iv);
// Make the encryptor or decryptor.
ICryptoTransform crypto_transform;
if (encrypt)
{
crypto_transform = aes_provider.CreateEncryptor(key, iv);
}
else
{
crypto_transform = aes_provider.CreateDecryptor(key, iv);
}
// Attach a crypto stream to the output stream.
// Closing crypto_stream sometimes throws an
// exception if the decryption didn't work
// (e.g. if we use the wrong password).
try
{
using (CryptoStream crypto_stream =
new CryptoStream(out_stream, crypto_transform,
CryptoStreamMode.Write))
{
// Encrypt or decrypt the file.
const int block_size = 1024;
byte[] buffer = new byte[block_size];
int bytes_read;
while (true)
{
// Read some bytes.
bytes_read = in_stream.Read(buffer, 0, block_size);
if (bytes_read == 0) break;
// Write the bytes into the CryptoStream.
crypto_stream.Write(buffer, 0, bytes_read);
}
} // using crypto_stream
}
catch
{
}
crypto_transform.Dispose();
}
// Use the password to generate key bytes.
private static void MakeKeyAndIV(string password, byte[] salt,
int key_size_bits, int block_size_bits,
out byte[] key, out byte[] iv)
{
Rfc2898DeriveBytes derive_bytes =
new Rfc2898DeriveBytes(password, salt, 1000);
key = derive_bytes.GetBytes(key_size_bits / 8);
iv = derive_bytes.GetBytes(block_size_bits / 8);
}
我尝试在提取后将其拆分但我无法再次检索新密钥而且我不知道我做错了什么。
答案 0 :(得分:0)
您可以在bytestobehidden
的开头添加几个字节,这将指示拆分流的位置。例如:
fileContainer = ...
RSAcipher = ...
byte[] header = new byte[3];
int fileLength = fileContainer.Length;
header[0] = (byte) ((fileLength >> 16) & 0xff);
header[1] = (byte) ((fileLength >> 8) & 0xff);
header[2] = (byte) (fileLength & 0xff);
byte[] bytestobehidden = Combine(header, fileContainer, RSAcipher);
您可以轻松修改Combine()
以接受三个字节的数组。提取秘密后,您可以
int fileLength = (int) (bytestobehidden[0] << 16) +
(int) (bytestobehidden[1] << 8) +
(int) bytestobehidden[2];
byte[] fileContainer = new byte[fileLength];
byte[] RSACipher = new byte[bytestobehidden.Length-fileLength-3];
System.Array.Copy(bytestobehidden, 3, fileContainer, 0, fileLength);
System.Array.Copy(bytestobehidden, fileLength+3, RSACipher, 0, bytestobehidden.Length-fileLength-3);
&
,>>
和<<
为bitwise operators。您可以将标头修改为仅2个字节,但您必须确保永远不会处理大于64 kB的文件大小。另一方面,3个字节可以编码最大16 MB的大小,我认为这就足够了。