昨天(Day22-資料傳輸安全(機密性) RSA x AES 混搭風(上))我們將RSA x AES 混搭風所需要的測試檔案以及AES加解密程式準備好,順便讓來自不同家族的RSA和AES了解彼此人生目標以及婚後的生活,今天來讓RSA x AES在眾人的祝福下,在一起~在一起~在一起。
因為測試的請款檔案是預備從商店端傳送到收單銀行,因此習慣上會定期由收單銀行端產生一組公私鑰。
私密金鑰(private key)銀行自己妥善保管,而公開金鑰(public key)則交給商店進行加密。
這邊我們呼叫C# RSA加密解演算法物件的ToXmlString,利用輸入的參數True或false就可以產生公鑰或私鑰。
後面介紹RSA時,我們再改成憑證的方式儲存RSA公私鑰,這邊先簡單使用xmlstring。
public void TestGenRsaKey()
{
//建立RSA演算法物件
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//顯示私密金鑰(FromXmlString),這一把要妥善保存。
Console.WriteLine($"private key:{rsa.ToXmlString(true)}");
//我是分隔線
Console.WriteLine("====================================");
//顯示公開金鑰(FromXmlString),這一把要交給商店。
Console.WriteLine($"public key:{rsa.ToXmlString(false)}");
}
執行結果:
私密金鑰(private key)
<RSAKeyValue> <Modulus>1YH2PKyMSjX/1Giw+y3/aIqXfqHas9llRJMyJrx++5tylWFsmP/UH3DvuUKoteEnGZKLxyug0scZ12kRKyyXXq6cYenV6TpZ7Ai2Wnxc9pHMJXO26GIdtgFRy93wFnMni0QCZ43YRyJ+SOzW+VnyUMGWD/a43eQucW+uju2a5V8=</Modulus>
<Exponent>AQAB</Exponent>
<P>5ztUfQSfJpVXuGisil3uxbGOLj3iJgA92mKkp8Jz7cR3Yt/RbMvivbJV6Di7HGJkKdeLP8dOHJvlySSB5xJJgw==</P>
<Q>7GCdUlF37/0IARjjVUKbKJjTiO2ETnwW2I9Sm+lJJr1Q+qTHmG1sErJqFqWWXjmOnxKR9VXTemtlWEk3goRZ9Q==</Q>
<DP>wprYPG9LUjmWHglaTQlJDvCj7J8AWWMSq10hnl61GoKix3/+zUW6ilQwoMQ+FWFpUx2ogADI6KL7/RDQkxx86Q==</DP>
<DQ>H398V0TN46fnEiZb3Lekb1N2FK/5ym+Up8TpcCc0/TmK+etNQY2LMi6eHmhwUhv/WkkiM/v80zpOZeZTxEuYpQ==</DQ>
<InverseQ>lRuu2nbptZizRNHncOXxOzXXInRa/Ay/m2IDLNecB2M7IrRRFxfQMT3ZxwVL29jO6QjhmRma5hyP/rCircKqNw==</InverseQ>
<D>P9wZXFh3tZKlLFEL7nT5mbkqStP6aCSz52jnbTKgAH2kLg3vv2t1dNoAuba4Y34uhbWRXUctWR34GrfwTKuPslRGs0EZzi6pdswSDDAJI61cGMGCMKB0znf0rdBedSScC8mJA4dVlQxpWs1ivENOv9irBXbnL9EbzpdFSRetdlE=</D>
</RSAKeyValue>
公開金鑰(public key)
<RSAKeyValue>
<Modulus>1YH2PKyMSjX/1Giw+y3/aIqXfqHas9llRJMyJrx++5tylWFsmP/UH3DvuUKoteEnGZKLxyug0scZ12kRKyyXXq6cYenV6TpZ7Ai2Wnxc9pHMJXO26GIdtgFRy93wFnMni0QCZ43YRyJ+SOzW+VnyUMGWD/a43eQucW+uju2a5V8=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
有沒有發現產生私密金鑰時,公開金鑰也在其中。
1.首先商家要先產生這次的會議金鑰(Session key)
2.商家使用會議金鑰(Session key)對檔案內容進行加密。
3.商家使用收單銀行的公開金鑰(public key)對會議金鑰(Session key)進行加密。
4.將步驟2.3檔案合併
[TestMethod]
public void TestEncryption()
{
//建立檔案
CreateFile();
//建立RSA演算法物件
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
string publicKey = @"<RSAKeyValue>
<Modulus>1YH2PKyMSjX/1Giw+y3/aIqXfqHas9llRJMyJrx++5tylWFsmP/UH3DvuUKoteEnGZKLxyug0scZ12kRKyyXXq6cYenV6TpZ7Ai2Wnxc9pHMJXO26GIdtgFRy93wFnMni0QCZ43YRyJ+SOzW+VnyUMGWD/a43eQucW+uju2a5V8=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>";
//載入公開金鑰(FromXmlString)
rsa.FromXmlString(publicKey);
//AES加密
//讀取會議金鑰(session key)資料
string SessionKey = "我是金鑰我是機密別和人說我是金鑰";
string IV = "00000000";
byte[] bSK = Encoding.Unicode.GetBytes(SessionKey);
byte[] bEncryptSK = rsa.Encrypt(bSK, false);
//AES檔案加密
string filecontent = System.IO.File.ReadAllText(@"C:\temp\transaction.txt");
string Encrypfilecontent = AESEncryption(SessionKey, IV, filecontent);
//寫出合併後的檔案(Session key(Encrypted) + filecontent(Encrypted))
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\temp\transaction(Encrypted).txt", false))
{
file.WriteLine(Convert.ToBase64String(bEncryptSK));
file.WriteLine("\t");
file.WriteLine(Encrypfilecontent);
}
}
加密前檔案:
加密後檔案:
1.銀行將加密後的檔案拆開為加密後的會議金鑰(Session key)及加密後的檔案內容兩部分。
2.銀行使用自己保管的私密金鑰(private key)對會議金鑰(Session key)進行解密。
3.使用步驟2解開的會議金鑰(Session key)對加密後的檔案內容進行解密。
[TestMethod]
public void TestDecryption()
{
//建立RSA演算法物件
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//private key(FromXmlString)
string privateKey = @"<RSAKeyValue>
<Modulus>1YH2PKyMSjX/1Giw+y3/aIqXfqHas9llRJMyJrx++5tylWFsmP/UH3DvuUKoteEnGZKLxyug0scZ12kRKyyXXq6cYenV6TpZ7Ai2Wnxc9pHMJXO26GIdtgFRy93wFnMni0QCZ43YRyJ+SOzW+VnyUMGWD/a43eQucW+uju2a5V8=</Modulus>
<Exponent>AQAB</Exponent>
<P>5ztUfQSfJpVXuGisil3uxbGOLj3iJgA92mKkp8Jz7cR3Yt/RbMvivbJV6Di7HGJkKdeLP8dOHJvlySSB5xJJgw==</P>
<Q>7GCdUlF37/0IARjjVUKbKJjTiO2ETnwW2I9Sm+lJJr1Q+qTHmG1sErJqFqWWXjmOnxKR9VXTemtlWEk3goRZ9Q==</Q>
<DP>wprYPG9LUjmWHglaTQlJDvCj7J8AWWMSq10hnl61GoKix3/+zUW6ilQwoMQ+FWFpUx2ogADI6KL7/RDQkxx86Q==</DP>
<DQ>H398V0TN46fnEiZb3Lekb1N2FK/5ym+Up8TpcCc0/TmK+etNQY2LMi6eHmhwUhv/WkkiM/v80zpOZeZTxEuYpQ==</DQ>
<InverseQ>lRuu2nbptZizRNHncOXxOzXXInRa/Ay/m2IDLNecB2M7IrRRFxfQMT3ZxwVL29jO6QjhmRma5hyP/rCircKqNw==</InverseQ>
<D>P9wZXFh3tZKlLFEL7nT5mbkqStP6aCSz52jnbTKgAH2kLg3vv2t1dNoAuba4Y34uhbWRXUctWR34GrfwTKuPslRGs0EZzi6pdswSDDAJI61cGMGCMKB0znf0rdBedSScC8mJA4dVlQxpWs1ivENOv9irBXbnL9EbzpdFSRetdlE=</D>
</RSAKeyValue>
";
//載入私密金鑰
rsa.FromXmlString(privateKey);
//讀取加密後的本文資料
string AllText = System.IO.File.ReadAllText(@"C:\temp\transaction(Encrypted).txt");
//使用分隔符號拆解
if (!AllText.Contains("\t"))
{
Console.WriteLine("明文與簽章資料缺少分隔符號\t");
return;
}
byte[] skText = Convert.FromBase64String(AllText.Split('\t')[0]);
string DataText = AllText.Split('\t')[1];
//(1)先解出Session key
byte[] bEncryptSK = rsa.Decrypt(skText, false);
//顯示Session key
Console.WriteLine(Encoding.Unicode.GetString(bEncryptSK));
//(2)解密檔案
string content = AESDecryption(Encoding.Unicode.GetString(bEncryptSK), "00000000", DataText);
//顯示檔案內容
Console.WriteLine(content);
//(3)重新寫出檔案給BIZ應用程式處理
using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"C:\temp\transaction(OK).txt", false))
{
file.WriteLine(content);
}
}
執行結果:
檔案解密成功:
從Day18起,我們用了6天時間複習檔案傳輸時的資料保護,有著重在資料完整性(data integrity),也有重點放在機密性(Confidentiality)與識別來源上的機制,希望我們在行駛到高速公路前,選擇一台更多備配有主被動安全的車輛,如果天有不測風雲之時,也能有更多面向保護車內乘客的安全。
[Day18] 資料傳輸安全(完整性)校驗值與雜湊值
[Day19] 資料傳輸安全(完整性)MAC訊息驗證碼 (上)
[Day20] 資料傳輸安全(完整性)MAC訊息驗證碼 (下)
[Day21] 資料傳輸安全(完整性)數位簽章
[Day22] 資料傳輸安全(機密性) RSA x AES 混搭風(上)
哈!明天我們來簡單複習加密通道。
托斯卡尼警車營運中
2011.10 攝於Toscana,Italy
Stanley大大,已經是第23天囉(標題好像有誤 XDD
每篇內容都好精采喔!!
謝謝Stanley大大的教學文章
謝謝小茶~
小茶大的文章也很棒!
哈!我們要一起衝線。加油!
Stanley大,我想要讓不同台電腦(用戶)間使用同一組金鑰,目前是使用Powershell建立憑證再匯出公私鑰,程式使用X509引用作RSA加解密,長度限制則是用分段加解密的方式處理。
想請教如果不使用將公私鑰匯出文字檔的方式保存,該怎麼從程式中保存由RSACryptoServiceProvider創建的公私鑰並可以傳給其他用戶(不同台電腦)呢?
現在的想法是使用金鑰容器保存,然後再匯出,只是這樣過程好像變得有些複雜。