2016-08-02 4 views
0

次のコードは、例示としてWindowsデータ保護APIを使用して、メモリ内のデータを暗号化することが可能である:暗号化されていないデータの長さを明らかにすることなくDPAPIで暗号化しますか?

byte[] toEncrypt = UnicodeEncoding.ASCII.GetBytes("ThisIsSomeData16"); 

Console.WriteLine("Original data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)); 
Console.WriteLine("Encrypting..."); 

// Encrypt the data in memory. 
EncryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon); 

Console.WriteLine("Encrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)); 
Console.WriteLine("Decrypting..."); 

// Decrypt the data in memory. 
DecryptInMemoryData(toEncrypt, MemoryProtectionScope.SameLogon); 

Console.WriteLine("Decrypted data: " + UnicodeEncoding.ASCII.GetString(toEncrypt)); 

は、ここでは、Microsoftのリファレンスを参照してください:https://msdn.microsoft.com/en-us/library/ms995355.aspx

をしかし、この例ではencyptedデータを元のデータと同じサイズです。元のファイルのファイルサイズを明らかにせずにDPAPIを使用してデータを暗号化する方法はありますか?例えば、生成された暗号文をキー内の「ランダムな」場所に隠すことは、1回のパッドで可能ですか?

+0

入力データをlength + data + paddingとして単純に構成しないのはなぜですか? –

+0

確かに可能ですが、これは解読後にデータを解析する必要がありますが、これは既に一般的な問題であると思われます。 –

+1

DPAPI暗号化の品質に依存し、既知の平文攻撃のもう一つの可能​​性は、鍵を生成し、適切なブロック暗号化( 'AesCryptoServiceProvider'など)に使用し、DPAPIで鍵を保護することです。したがって、既知の長さは問題になりません。 –

答えて

0

DPAPI BLOB内のデータを暗号化し、そのBLOBを復号化すると、まったく同じデータが返されます。これがその全体像です。 暗号化されたDPAPIブロブを見て、システムがAESを使用している場合(Win7以降のデフォルトのように)、暗号データ​​のサイズが最も近いため、誰でも秘密のおおよその長さを推測できますブロックサイズの倍数を実際の長さに置き換えます。例えば秘密が17バイトである場合、DPAPIプロバイダは、これらのバイトの後に15バイトの値0xFを暗号化して、AESが暗号化する2つのブロックを作成する(そして、解読時にそれらのバイトを取り除く)。したがって、DPAPIデータのサイズを見るだけで、その秘密が16〜31バイトの長さであることがわかります。

これが問題になる場合は、あなた自身の詰め物にあなた自身の秘密をラップする必要があります。保護するデータとして作成する:「秘密の長さ」秘密の「ランダムなもの」をDPAPIに入れます。誰でもこのデータのおおよその長さ(最大16バイト)を推測することができますが、実際の秘密の長さではなく、些細な上界を除いてはもちろんです。正当なユーザがDPAPIブロブの解読を取り戻すとき、彼は長さフィールド(それ自体既知の固定長さを持つべきである)から秘密を推論することができる。 DPAPIでは、データが改ざんされていないことが保証されています(HMACが使用されているため)。

保護したい秘密に表示されていないことがわかっているバイトを使用して、それを秘密データの最後のマーカーバイトとして使用することもできます。例えば。 C文字列の場合は0x0。しかし、長さを追加することはよりフェイルセーフです、と私は思います。

関連する問題