前言
由于客戶網(wǎng)絡(luò)安全限制,連接到互聯(lián)網(wǎng)的設(shè)備不能訪問內(nèi)網(wǎng)。
需要先從客戶端應(yīng)用中導(dǎo)出數(shù)據(jù)到文件,再將文件復(fù)制到U盤,最后通過內(nèi)網(wǎng)機(jī)器上傳數(shù)據(jù)。
如何保證,在復(fù)制、傳輸過程中,文件的安全性?
思路
首先想到的是對(duì)文件進(jìn)行加密。但是文件本身可能非常大,因此只能采取對(duì)稱加密(AES)。
如果將對(duì)稱加密的密鑰存儲(chǔ)在客戶端的應(yīng)用里,可能導(dǎo)致密鑰泄露。
最好是每次加密都使用不同的AES密鑰。
現(xiàn)在的關(guān)鍵是,如何將這個(gè)隨機(jī)AES密鑰傳輸給解密方?
根據(jù)我們?cè)凇墩?qǐng)收藏!這可能是目前最安全的數(shù)據(jù)加密傳輸解決方案》中的思路,我們可以采用RSA公鑰加密AES密鑰,并將其作為文件的一部分發(fā)給解密方。
加密文件將由以下幾個(gè)部分組成:
- 256字節(jié)RSA加密后的AES密鑰
- 16字節(jié)初始化向量
- AES加密的文件數(shù)據(jù)
解密方首先讀取并使用RSA私鑰解密出AES密鑰,再用AES密鑰解密出實(shí)際的文件數(shù)據(jù)。
實(shí)現(xiàn)
理清了思路,讓我們來看一下實(shí)現(xiàn)。
首先是加密代碼:
(byte[] aesKey, byte[] aesIV) = AesHelper.Create();
using (var origFileStream = File.OpenRead("原始文件"))
{
using (var encryptFileStream = File.Create("加密文件"))
{
await encryptFileStream.WriteAsync(RSAHelper.Encrypt(aesKey));
await encryptFileStream.WriteAsync(aesIV);
using (var cryptoStream = AesHelper.CreateWriteStream(encryptFileStream, aesKey, aesIV))
{
await origFileStream.CopyToAsync(cryptoStream);
}
}
}
然后是解密代碼:
using (var decryptFileStream = File.OpenRead("解密文件"))
{
using (var encryptFileStream = File.OpenRead("加密文件"))
{
var aesKeyData = new byte[256];
await encryptFileStream.ReadAsync(aesKeyData, 0, aesKeyData.Length);
var aesKey = RSAHelper.Decrypt(aesKeyData);
var aesIVData = new byte[16];
await encryptFileStream.ReadAsync(aesIVData, 0, aesIVData.Length);
var aesIV = aesIVData;
using (var cryptoStream = AesHelper.CreateReadStream(encryptFileStream, aesKey, aesIV))
{
await cryptoStream.CopyToAsync(decryptFileStream);
}
}
}
結(jié)論
通過使用RSA+AES,同時(shí)保證了密鑰和數(shù)據(jù)的安全性。
如果你也碰到了類似需求,不妨試試本文的實(shí)現(xiàn)方案。