LoginSignup
3
6

More than 5 years have passed since last update.

Windows API では、.NetのAPIから大きく変更されているようです。hibaraさんの記事を参考にしてみたのですが、AesManagedをはじめとしたクラスはユニバーサルWindowsアプリの開発では利用できませんでした。

そこで、記事を参考に同様のことをWindows APIで行ってみます。

暗号化

SymmetricAlgorithmNames.AesCbcPkcs7で取得したSymmetricKeyAlgorithmProviderを用いると、CBCでPKCS7なAES暗号を利用することができます。

private static readonly string ALGORITHM_NAME = SymmetricAlgorithmNames.AesCbcPkcs7;

private IBuffer toEncryptedBuffer(IBuffer buffer, string rawPassword, out IBuffer salt, out IBuffer iv)
{
    // https://msdn.microsoft.com/en-us/library/windows/apps/windows.security.cryptography.core.symmetrickeyalgorithmprovider.aspx
    SymmetricKeyAlgorithmProvider algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(ALGORITHM_NAME);

    salt = CryptographicBuffer.GenerateRandom(32);
    var derviedKey = createDerviedKey(algorithm, rawPassword, salt);

    iv = CryptographicBuffer.GenerateRandom(algorithm.BlockLength);

    return CryptographicEngine.Encrypt(derviedKey, buffer, iv);
}

createDerviedKeyメソッドではキーの生成を行います。元の記事では Rfc2898DeriveBytes を利用していますが、RFC2898とPBKDF2は同じアルゴリズムを指しています

private const uint SALT_ITERATION_COUNT = 10000;

private CryptographicKey createDerviedKey(SymmetricKeyAlgorithmProvider algorithm, string rawPassword, IBuffer salt)
{
    KeyDerivationAlgorithmProvider pbkdf2 = KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha256);
    IBuffer passwordBuffer = CryptographicBuffer.ConvertStringToBinary(rawPassword, BinaryStringEncoding.Utf8);
    CryptographicKey key = pbkdf2.CreateKey(passwordBuffer);

    KeyDerivationParameters parameters = KeyDerivationParameters.BuildForPbkdf2(salt, SALT_ITERATION_COUNT);

    IBuffer derviedKeyMaterial = CryptographicEngine.DeriveKeyMaterial(key, parameters, 32);
    return algorithm.CreateSymmetricKey(derviedKeyMaterial);
}

暗号化前に圧縮をかける定石は、これまで通りDeflateStreamが使えます。

複合

先ほどのcreateDerviedKeyを使ってほとんど似たようなコードで複合することができます。

private IBuffer toDecryptedBuffer(IBuffer buffer, string rawPassword, IBuffer salt, IBuffer iv)
{
    SymmetricKeyAlgorithmProvider algorithm = SymmetricKeyAlgorithmProvider.OpenAlgorithm(ALGORITHM_NAME);

    var derviedKey = createDerviedKey(algorithm, rawPassword, salt);

    return CryptographicEngine.Decrypt(derviedKey, buffer, iv);
}

解凍はIBuffer.AsStream()を使ってStreamにした後にDeflateStreamに通します。

こちらも誤ったパスワードで複合した際のチェックを行っていませんが、だいたいは解凍時におかしくなってエラーになるっぽいです。

全体のプロジェクト

暗号化されたテキストを読み書きできるツールを作ってみました。

3
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6