大きなファイルを暗号化して保存してから、後で復号化する必要があります。それをする最善の方法は何ですか?私はRSA暗号化が高価であると聞き、RSAを使ってAES鍵を暗号化し、AES鍵を使って大きなファイルを暗号化することを勧めました。例を挙げればどんな提案も素晴らしいでしょう。大きなファイルの暗号化/復号化(.NET)
答えて
説明した方法は、データがあるマシン(サーバーなど)で暗号化され、次に別のマシン(クライアント)によって復号化される場合に使用されます。サーバーは、新しく生成された鍵で対称鍵暗号化(パフォーマンス用)を使用してデータを暗号化し、この対称鍵を公開鍵(クライアントの秘密鍵に一致)で暗号化します。サーバーは、クライアントに暗号化されたデータと暗号化対称鍵の両方を送信します。クライアントは、その秘密鍵で対称鍵を復号化し、この対称鍵を使用してデータを復号化することができます。 同じマシン上のデータを暗号化して解読する場合は、RSAとAESの両方を使用して暗号鍵を別のマシンに渡そうとしない場合があります。
私たちがそれを見ると、私たちはすべて高価であるとはいえ、ある生物は小さいです。ウインクウインク。
お使いの環境で、次のようなものをベンチマーク試してみて、あなたがでている場所を参照してください。
EDIT 2012年2月13日:コードは賢くも注目(いつの間にか)私はなってきたように更新されましたいくつかのcut'n'pasteエラーがうかがっていた。Mea culpa。
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
...
// Rfc2898DeriveBytes constants:
public readonly byte[] salt = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Must be at least eight bytes. MAKE THIS SALTIER!
public const int iterations = 1042; // Recommendation is >= 1000.
/// <summary>Decrypt a file.</summary>
/// <remarks>NB: "Padding is invalid and cannot be removed." is the Universal CryptoServices error. Make sure the password, salt and iterations are correct before getting nervous.</remarks>
/// <param name="sourceFilename">The full path and name of the file to be decrypted.</param>
/// <param name="destinationFilename">The full path and name of the file to be output.</param>
/// <param name="password">The password for the decryption.</param>
/// <param name="salt">The salt to be applied to the password.</param>
/// <param name="iterations">The number of iterations Rfc2898DeriveBytes should use before generating the key and initialization vector for the decryption.</param>
public void DecryptFile(string sourceFilename, string destinationFilename, string password, byte[] salt, int iterations)
{
AesManaged aes = new AesManaged();
aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
aes.KeySize = aes.LegalKeySizes[0].MaxSize;
// NB: Rfc2898DeriveBytes initialization and subsequent calls to GetBytes must be eactly the same, including order, on both the encryption and decryption sides.
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt, iterations);
aes.Key = key.GetBytes(aes.KeySize/8);
aes.IV = key.GetBytes(aes.BlockSize/8);
aes.Mode = CipherMode.CBC;
ICryptoTransform transform = aes.CreateDecryptor(aes.Key, aes.IV);
using (FileStream destination = new FileStream(destinationFilename, FileMode.CreateNew, FileAccess.Write, FileShare.None))
{
using (CryptoStream cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write))
{
try
{
using (FileStream source = new FileStream(sourceFilename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
source.CopyTo(cryptoStream);
}
}
catch (CryptographicException exception)
{
if (exception.Message == "Padding is invalid and cannot be removed.")
throw new ApplicationException("Universal Microsoft Cryptographic Exception (Not to be believed!)", exception);
else
throw;
}
}
}
}
/// <summary>Encrypt a file.</summary>
/// <param name="sourceFilename">The full path and name of the file to be encrypted.</param>
/// <param name="destinationFilename">The full path and name of the file to be output.</param>
/// <param name="password">The password for the encryption.</param>
/// <param name="salt">The salt to be applied to the password.</param>
/// <param name="iterations">The number of iterations Rfc2898DeriveBytes should use before generating the key and initialization vector for the decryption.</param>
public void EncryptFile(string sourceFilename, string destinationFilename, string password, byte[] salt, int iterations)
{
AesManaged aes = new AesManaged();
aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
aes.KeySize = aes.LegalKeySizes[0].MaxSize;
// NB: Rfc2898DeriveBytes initialization and subsequent calls to GetBytes must be eactly the same, including order, on both the encryption and decryption sides.
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, salt, iterations);
aes.Key = key.GetBytes(aes.KeySize/8);
aes.IV = key.GetBytes(aes.BlockSize/8);
aes.Mode = CipherMode.CBC;
ICryptoTransform transform = aes.CreateEncryptor(aes.Key, aes.IV);
using (FileStream destination = new FileStream(destinationFilename, FileMode.CreateNew, FileAccess.Write, FileShare.None))
{
using (CryptoStream cryptoStream = new CryptoStream(destination, transform, CryptoStreamMode.Write))
{
using (FileStream source = new FileStream(sourceFilename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
source.CopyTo(cryptoStream);
}
}
}
}
この例では、AESを使用した暗号化/復号化のみを行っています。RSAとプロファイルの両方で同様のことを試してみることを意味しますか? – kalrashi
それはあなた次第です。あなたの質問は、データ、ファイルのサイズ、ネットワーク転送や関連する暴露、利用可能な処理リソースなどに対する認識された脅威については説明しませんでした。この場合、環境内の暗号化コストに関するベンチマークデータを少なくとも収集し、そこから作業することはうまくいくように思えます。他のものは、公開鍵と秘密鍵の暗号化と、異なるアルゴリズムの相対的な強さに触れてきました。 – HABO
「埋め込みが無効で、削除できません」という問題を回避するには例外として、暗号化側は 'source.CopyTo(crytoStream);の後に' source.FlushFinalBlock() 'を呼び出さなければなりません。 – DipSwitch
あなたは、非対称暗号を聞いたように、RSAのように、対称暗号(例えばAES)よりもはるかに遅いですが、それはそれが利点(単純鍵管理、保護するために、例えば、単一の秘密鍵)です持っています。
鍵は、他の鍵(多くの秘密鍵と低速)の不都合を無視して、両方の利点(非対称の秘密鍵と対称の速度)を使用することです。
大容量のファイルを暗号化する(はるかに高速に)ために使用される(対称)秘密鍵を暗号化するために、ファイルごとに1回(巨大なパフォーマンスへの影響なし)RSAを使用します。この* の対称キーのをラップすると、1つの秘密キーしか管理できません。
これは、C#と.NETフレームワーク(Microsoft of Mono)を使用してこれを行う例を示した、私の古い(ただしまだ真実の)blog postへのリンクです。これは役立つかもしれ
ありがとうございます。この例はとても役に立ちました。 – kalrashi
/// Encrypts a file using Rijndael algorithm.
///</summary>
///<param name="inputFile"></param>
///<param name="outputFile"></param>
private void EncryptFile(string inputFile, string outputFile)
{
try
{
string password = @"myKey123"; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
string cryptFile = outputFile;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
cs.WriteByte((byte)data);
fsIn.Close();
cs.Close();
fsCrypt.Close();
}
catch
{
MessageBox.Show("Encryption failed!", "Error");
}
}
///
/// Decrypts a file using Rijndael algorithm.
///</summary>
///<param name="inputFile"></param>
///<param name="outputFile"></param>
private void DecryptFile(string inputFile, string outputFile)
{
{
string password = @"myKey123"; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateDecryptor(key, key),
CryptoStreamMode.Read);
FileStream fsOut = new FileStream(outputFile, FileMode.Create);
int data;
while ((data = cs.ReadByte()) != -1)
fsOut.WriteByte((byte)data);
fsOut.Close();
cs.Close();
fsCrypt.Close();
}
}
ソース:ここhttp://www.codeproject.com/Articles/26085/File-Encryption-and-Decryption-in-C
このコードにはいくつかの重大な問題があります:a)パスワードの長さが十分でない場合は動作しませんが、通常はパスワードが低いエントロピーでキーとして直接使用できないという問題があります。 b)キーをIVとして使用すると、この決定論的な暗号化が行われるため、意味的に安全ではありません。 IVはランダムに生成されなければならない。それは秘密である必要はなく、予測不能なだけなので、単純に暗号文の前に書き込まれ、復号化中に使用されます。 c)認証なし!受信者がこれを検出することなく、暗号文を変更することができます。 –
- 1. 別ファイルのXML暗号化/復号化
- 2. ファイルの暗号化と復号化
- 3. ファイルの復号化と暗号化
- 4. アセンブラXOR暗号化/復号化ファイル
- 5. RSA暗号化/復号化
- 6. 暗号化と復号化
- 7. AES暗号化/復号化
- 8. 暗号化/復号化soll
- 9. 復号化、暗号化
- 10. シンプルな暗号化/復号化
- 11. 暗号ブロックチェーンの復号XOR「暗号化」
- 12. メモリの少ない大容量ファイルの暗号化/復号化のベストプラクティス
- 13. iOSとAndroidでのAES暗号化、C#.NETでの復号化
- 14. カスタム暗号化暗号化/復号化ストリーム
- 15. .Net暗号化
- 16. シーケンシャル.NET DESCryptoServiceProviderの暗号化と復号化は、第96
- 17. モバイルと.net webservicesでの暗号化と復号化
- 18. perlの暗号化、delphi7の復号化
- 19. AES256暗号化/復号化の速度
- 20. SWIFTの暗号化と復号化
- 21. Muleコミュニティ版の暗号化/復号化
- 22. RSA暗号化/復号化の実装
- 23. パスワードの暗号化/復号化スプリングセキュリティ
- 24. ESP8266 AESの暗号化 - 復号化
- 25. DataTableオブジェクトの暗号化と復号化
- 26. ASP.net ViewStateの暗号化と復号化
- 27. ESAPIの暗号化と復号化
- 28. Md5ハッシュの暗号化と復号化
- 29. Java暗号化(PBEWithMD5AndDES)の復号化(PBEWithMD5AndDES)
- 30. SQL Serverの暗号化と復号化
は一例であり、[ブログの投稿](http://www.technical-recipes.com/2013/using-rsa-to-ダウンロード可能な[Visual Studio 2010プロジェクト](http://www.technical-recipes.com/Downloads/crypt.7z)でダウンロードできます。 – AndyUK