OpenSSLを使用してファイルを暗号化/復号化する方法は?


205

1つのパスワードを使用して1つのファイルを暗号化および復号化したい。

OpenSSLを使用してそれを行うにはどうすればよいですか?


2
を使用して、パスワードからキーとIVを導出する必要がありますPKCS5_PBKDF2_HMACEVP_*暗号化と復号化には関数を使用する必要があります。OpenSSL wikiのEVP対称暗号化および復号化を参照してください。実際、機密性と信頼性の両方を提供するため、おそらく認証された暗号化を使用する必要があります。OpenSSL wikiのEVP Authenticated Encryption and Decryptionを参照してください。
jww

3
OpenSSLが必要な理由を質問から理解できません。以下のコメントは、GPGの方が優れていることを示しています。これもセキュリティ上の理由からです。stackoverflow.com/a/31552829/952234私は反対票を投じます。
Yaroslav Nikitenko 2016年

回答:


261

セキュリティ警告:AES-256-CBCは認証された暗号化を提供せず、オラクル攻撃のパディングに対して脆弱です。代わりに年齢のようなものを使用する必要があります。

暗号化:

openssl aes-256-cbc -a -salt -in secrets.txt -out secrets.txt.enc

復号化:

openssl aes-256-cbc -d -a -in secrets.txt.enc -out secrets.txt.new

さまざまなフラグの詳細


18
OPのユースケースによっては、(この記事の執筆時点では)回答が最適ではない可能性があります。具体的には、パラメーター "-a"はおそらく最適ではなく、答えはその使用法を説明していません。「-a」は通常、暗号化された出力がASCII /テキスト形式で送信される場合に使用され、バイナリ形式と比較して出力サイズが増加する効果があります。元のポスターは出力形式を指定していないので、少なくともこれについて言及する必要があると思います。回答:stackoverflow.com/a/31552829/952234を参照してください。このタスクには、opensslの代わりにgpgを使用する必要がある理由についての注記も含まれています。
moo 2016年

7
キーの派生がないため、上記のコマンドは使用しないでください。詳しくはこちらをご覧ください:opensslの弱い鍵の導出
jonasl

キーを指定するか、それがどこから来たかについても言及する必要があります。強化されていますか?
2016年

2
最新のmanページによると、@ jonaslは次のように述べています。「Openssl 1.1.0では、デフォルトのダイジェストがMD5からSHA256に変更されました。」出典:github.com/openssl/openssl/blob/master/doc/man1/enc.pod
Kebman

2
@Kebmanからのコメントに追加して、-md sha256別のマシンでこのファイルを使用する場合は、encodeおよびdecodeコマンドに追加できます。OpenSSLバージョンの非互換性/相違点に対する
対策が

162

短い答え:

gpg代わりに使用する可能性があるopensslので、この回答の最後にある「その他の注意事項」を参照してください。しかし、以下を使用して質問に答えるにはopenssl

暗号化するには:

openssl enc -aes-256-cbc -in un_encrypted.data -out encrypted.data

復号化するには:

openssl enc -d -aes-256-cbc -in encrypted.data -out un_encrypted.data

注:暗号化または復号化するときに、パスワードの入力を求められます。


長い答え:

の情報源としては、httpsopenssl enc//www.openssl.org/docs/man1.1.1/man1/enc.htmlが最適です

コマンドライン: openssl enc次の形式を取ります:

openssl enc -ciphername [-in filename] [-out filename] [-pass arg]
[-e] [-d] [-a/-base64] [-A] [-k password] [-kfile filename] 
[-K key] [-iv IV] [-S salt] [-salt] [-nosalt] [-z] [-md] [-p] [-P] 
[-bufsize number] [-nopad] [-debug] [-none] [-engine id]

あなたの質問に関して最も有用なパラメータの説明:

-e
    Encrypt the input data: this is the default.

-d    
    Decrypt the input data.

-k <password>
    Only use this if you want to pass the password as an argument. 
    Usually you can leave this out and you will be prompted for a 
    password. The password is used to derive the actual key which 
    is used to encrypt your data. Using this parameter is typically
    not considered secure because your password appears in 
    plain-text on the command line and will likely be recorded in 
    bash history.

-kfile <filename>
    Read the password from the first line of <filename> instead of
    from the command line as above.

-a
    base64 process the data. This means that if encryption is taking 
    place the data is base64 encoded after encryption. If decryption 
    is set then the input data is base64 decoded before being 
    decrypted.
    You likely DON'T need to use this. This will likely increase the
    file size for non-text data. Only use this if you need to send 
    data in the form of text format via email etc.

-salt
    To use a salt (randomly generated) when encrypting. You always
    want to use a salt while encrypting. This parameter is actually
    redundant because a salt is used whether you use this or not 
    which is why it was not used in the "Short Answer" above!

-K key    
    The actual key to use: this must be represented as a string
    comprised only of hex digits. If only the key is specified, the
    IV must additionally be specified using the -iv option. When 
    both a key and a password are specified, the key given with the
    -K option will be used and the IV generated from the password 
    will be taken. It probably does not make much sense to specify 
    both key and password.

-iv IV
    The actual IV to use: this must be represented as a string 
    comprised only of hex digits. When only the key is specified 
    using the -K option, the IV must explicitly be defined. When a
    password is being specified using one of the other options, the 
    IV is generated from this password.

-md digest
    Use the specified digest to create the key from the passphrase.
    The default algorithm as of this writing is sha-256. But this 
    has changed over time. It was md5 in the past. So you might want
    to specify this parameter every time to alleviate problems when
    moving your encrypted data from one system to another or when
    updating openssl to a newer version.

その他の注意事項:

OpenSSLについて具体的に質問しましたが、この記事に基づく暗号化の目的で、代わりにGPGを使用することを検討してください。オフサイトバックアップの暗号化にはOpenSSLとGPGを使用しますか?

GPGを使用して同じことを行うには、次のコマンドを使用します。

暗号化するには:

gpg --output encrypted.data --symmetric --cipher-algo AES256 un_encrypted.data

復号化するには:

gpg --output un_encrypted.data --decrypt encrypted.data

注:暗号化または復号化するときに、パスワードの入力を求められます。


8
OpenSSLよりもGPGを優先することについての素晴らしいコメント。OpenSSLがそのような弱いパスワードから派生したハッシュをキーに使用しているのは驚くべきことです!
マーク・

2
-MDオプションを使用せずに、古いのopensslに暗号化されたファイルとの互換性のために、「-MD MD5」オプションを指定して使用してください、そうでなければ、ファイルは新しいシステムで復号化しないことを見つける:github.com/libressl-portable/ portable / issues / 378
Sam Liddicott、2018

1
opensslのバージョン間でデフォルト値が異なります。1.0.xは、-mdオプションにデフォルトのmd5を使用します。バージョン1.1.xはsha256を使用します。暗号化を解除して「:デジタルエンベロープルーチン:EVP_DecryptFinal_ex:bad暗号化解除」エラーが発生した場合。「-md md5」または「-md sha256」を指定してみてください。
txyoji

1
「暗号化または復号化するときにパスワードの入力を求められます。」gpgパスワードの入力を求められることなくファイルを復号化できます。パスワードが一定期間保存されているようですが、これは望ましくありません。
user76284

1
@moo エージェントが実行中であっても、--no-symkey-cachegpgを--symmetricで使用するとキャッシュが無効になるようです。
user76284

32

暗号化:

openssl enc -in infile.txt -out encrypted.dat -e -aes256 -k symmetrickey

復号化:

openssl enc -in encrypted.dat -out outfile.txt -d -aes256 -k symmetrickey

詳細については、openssl(1)ドキュメントを参照してください。


11
平文パスワードを使用するには、交換する-k symmetrickey-pass stdin-pass 'pass:PASSWORD'
Zenexer

3
キーの派生がないため、上記のコマンドは使用しないでください。詳しくはこちらをご覧ください:opensslの弱い鍵の導出
jonasl

4
@jonaslのコメントに関連して、-k symmetrickey誤解を招く可能性があることに注意してください。この-kオプションは、OpenSSLが対称鍵を導出するパスワードを指定するために使用されます。対称鍵を指定する場合は、-Kオプションを使用する必要があります。
user1071847 2017

13

OPENSSLデフォルトのキー派生を使用しないでください。

現在受け入れられている回答はそれを利用しており、もはや推奨されておらず安全ではありません。

攻撃者がキーをブルートフォースすることは非常に現実的です。

https://www.ietf.org/rfc/rfc2898.txt

PBKDF1は、MD2 [6]、MD5 [19]、またはSHA-1 [18]であるハッシュ関数を適用してキーを導出します。派生キーの長さは、ハッシュ関数出力の長さによって制限されます。これは、MD2およびMD5の場合は16オクテット、SHA-1の場合は20オクテットです。PBKDF1は、PKCS#5 v1.5の鍵導出プロセスと互換性があります。PBKDF1は、既存のアプリケーションとの互換性のためだけに使用することをお勧めします。これにより、PBKDF1が生成するキーは、アプリケーションによっては十分に大きくない場合があります。

PBKDF2は、疑似ランダム関数(例については付録B.1を参照)を適用してキーを導出します。派生キーの長さは基本的に無制限です。(ただし、派生キーの最大有効検索スペースは、基になる疑似ランダム関数の構造によって制限されることがあります。詳細については、付録B.1を参照してください。)PBKDF2は、新しいアプリケーションに推奨されます。

これを行う:

openssl enc -aes-256-cbc -pbkdf2 -iter 20000 -in hello -out hello.enc -k meow

openssl enc -d -aes-256-cbc -pbkdf2 -iter 20000 -in hello.enc -out hello.out

:復号化の反復は、暗号化の反復と同じにする必要があります。

反復回数は10000以上にする必要があります。反復回数の良い答えは次のとおりです。https//security.stackexchange.com/a/3993

また、ここにはGPGを推奨する十分な人がいます。いまいましい質問を読んでください。


4

暗号化するには:

$ openssl bf < arquivo.txt > arquivo.txt.bf

復号化するには:

$ openssl bf -d < arquivo.txt.bf > arquivo.txt

bf === CBCモードのBlowfish



3

OpenSSL CLIは、弱い非標準アルゴリズムを使用してパスフレーズをキーに変換し、GPGをインストールすると、ホームディレクトリに追加されたさまざまなファイルとgpg-agentバックグラウンドプロセスが実行されることに注意してください。最大の移植性と既存のツールによる制御が必要な場合は、PHPまたはPythonを使用して下位レベルのAPIにアクセスし、完全なAESキーとIVを直接渡すことができます。

Bashを介したPHP呼び出しの例:

IV='c2FtcGxlLWFlcy1pdjEyMw=='
KEY='Twsn8eh2w2HbVCF5zKArlY+Mv5ZwVyaGlk5QkeoSlmc='
INPUT=123456789023456

ENCRYPTED=$(php -r "print(openssl_encrypt('$INPUT','aes-256-ctr',base64_decode('$KEY'),OPENSSL_ZERO_PADDING,base64_decode('$IV')));")
echo '$ENCRYPTED='$ENCRYPTED
DECRYPTED=$(php -r "print(openssl_decrypt('$ENCRYPTED','aes-256-ctr',base64_decode('$KEY'),OPENSSL_ZERO_PADDING,base64_decode('$IV')));")
echo '$DECRYPTED='$DECRYPTED

これは出力します:

$ENCRYPTED=nzRi252dayEsGXZOTPXW
$DECRYPTED=123456789023456

PHPのopenssl_pbkdf2関数を使用して、パスフレーズをキーに安全に変換することもできます。


openssl CLIが実装され、パスワードハッシュにPBKDF2を使用する必要があることをユーザーに警告します。ただし、デフォルトの反復回数は非常に少なく、はるかに大きくする必要があります。
アンソニー

2

私がオンラインで見つけたオープンソースプログラムがあり、opensslを使用してファイルを暗号化および復号化しています。単一のパスワードでこれを行います。このオープンソーススクリプトの優れた点は、元の暗号化されていないファイルを細断処理して削除することです。しかし、危険なのは、元の暗号化されていないファイルがなくなったら、パスワードを覚えていることを確認する必要があることです。

ここにリンクがgithubにあります

https://github.com/EgbieAnderson1/linux_file_encryptor/blob/master/file_encrypt.py


ファイルの暗号化にopensslを使用すると状況が変わります。オプションははるかに多く、暗号化されたファイルを正常に復号化するには、覚えておく必要があります。これに対する一つの解決策は、「キープアウト」である antofthy.gitlab.io/software/#keepout
アンソニー

2

他の回答で述べたように、opensslの以前のバージョンでは、弱い鍵導出関数を使用して、パスワードからAES暗号鍵を導出していました。ただし、openssl v1.1.1は、より強力なキー派生関数をサポートしています。キーはpbkdf2、ランダムに生成されたソルトを使用してパスワードから派生し、sha256ハッシュの複数の反復(デフォルトでは10,000)です。

ファイルを暗号化するには:

 openssl aes-256-cbc -e -salt -pbkdf2 -iter 10000 -in plaintextfilename -out encryptedfilename

ファイルを復号化するには:

  openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename

これらのオプションは変化し続けるため、opensslで暗号化された各ファイルの作成時に使用されたオプションの記録も保持する必要があります。特に、反復回数は時間とともに増加するはずです。一つの解決策は、OpenSSL ENC ...「キープアウト」の周りなどの比較的単純なラッパーを参照してください antofthy.gitlab.io/software/#keepout それはより多くのOpenSSLを含めるように拡張することができ、時間が経ついます。
アンソニー

@anthonyは便利なプロジェクトのようです。github.com/meixler/web-browser-based-file-encryption-decryption
mti2935

0

mti2935の良い答えに対する追加コメント。

イテレーションが高いほどブルートフォースに対する保護が向上するようです。パフォーマンス/リソースの面で余裕があるため、イテレーションを高くする必要があります。

私の古いIntel i3-7100では、かなり大きなファイル1.5GBを暗号化します:

 time openssl enc -aes256 -e -pbkdf2 -iter 10000 -pass pass:"mypassword" -in "InputFile" -out "OutputFile"
 Seconds: 2,564s

 time openssl enc -aes256 -e -pbkdf2 -iter 262144 -pass pass:"mypassword" -in "InputFile" -out "OutputFile"
 Seconds:  2,775s

実際には違いはありませんが、メモリ使用量はチェックしていません(?)

今日のGPUと明日はさらに速いので、毎秒10億回のブルートフォースの反復が可能だと思います。

12年前、a NVIDIA GeForce 8800 Ultraは200,000百万/秒を超える反復を繰り返すことができました(ただしMD5ハッシュ)

ソース:Ainane-Barrett-Johnson-Vivar-OpenSSL.pdf

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.