0

Office365 配布リストを PHP で記述された Sendy (sendy.co) に同期する C# での統合を開発しています。

PHP アプリケーションでは、いくつかの ID が暗号化されています。「秘密の」ID を検索しなくても API を使用して通信できるように、C# でも同じことを実現したいと考えています。

これは、これらの ID を計算するアプリケーションの PHP のコードです (パスワードを置き換えました)。

$encrypted = openssl_encrypt($in, 'AES-256-CBC', 'API_KEY', 0, 'SECRET_PASSWORD');
$encrypted = str_replace('/', '892', $encrypted);
$encrypted = str_replace('+', '763', $encrypted);
$encrypted = str_replace('=', '', $encrypted);

PHPスクリプトをどこかにホストしてC#アプリケーションから呼び出すことでこの「問題」を克服しましたが、オープンソースにしたいので、これをアプリケーションに統合したいと考えています。

.NET の .NET から始めなければAesCryptoServiceProviderならないと思いますが、うまくいかないようです (キーの長さなどで例外が発生します)。

これまでのところ、私はこれを試しました:

    public static string Execute()
    {
        // openssl_encrypt ( string $data , string $method , string $password [, int $options = 0 [, string $iv = "" ]] )
        var aes = new AesCryptoServiceProvider();
        aes.KeySize = 256;

        // Fixed password in code
        aes.Key = Encoding.UTF8.GetBytes("FIXED PASSWORD");
        // API = IV
        aes.IV = Encoding.UTF8.GetBytes("SENDY API KEY");

        aes.Mode = CipherMode.CBC;

        // Trying to encrypt "36" in this case
        byte[] src = Encoding.Unicode.GetBytes("36");

        // Actual encryption
        using (var encrypt = aes.CreateEncryptor())
        {
            byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);

            // Convert byte array to Base64 strings
            return Convert.ToBase64String(dest);
        }
    }

ただし、これにより、IV がアルゴリズムのブロック サイズと一致しないという例外がスローされます。

PHP の openssl_encrypt メソッドは、サンプル内の特定の API KEY から実際の IV を派生させていると思いますが (つまり、$password パラメーター)、C# で同じことを達成できるドキュメントはあまり見つかりません。

4

1 に答える 1

0

"SENDY API KEY"iv のサイズは、AES の場合は 16 バイト、わずか 13バイトのブロック サイズと等しくなければなりません。

iv は、暗号化ごとに異なるランダム値である必要があります。復号化中に使用するために、暗号化されたデータの先頭に追加するだけです。

次に、256 ビットのキー サイズを指定しましたが、キー"FIXED PASSWORD"は 14 バイトしかありません。同じ 128、192、または 256 ビット (16、24、または 32 バイト) にします。128 ビットを超えるキーを使用する必要はありません。

パスワードをキーに直接使用しないでください。キーは、PBKFD2 などの関数を使用してパスワードから導出する必要があります。

AES はブロック暗号です。入力は、長さがブロック サイズの倍数である必要があります。この入力のパディングを実現するには、必要です。通常、PKCS#7 (旧 PKCS#5) のパディングが使用されます。これは、おそらく OpenSSL のデフォルトです。暗号化/復号化は、このパディングを自動的に追加/削除する必要があります。ただし、これは、暗号化されたデータの長さが入力よりも 1 バイトから 16 バイト長くなることを意味します。たとえば、暗号化する"36"と、出力の長さは 16 バイトになります。

これらすべてを正しくまとめるのは難しい場合があります。RNCryptor-phpdefuseなどの総合的なソリューションの使用を検討してください。

于 2016-07-13T18:34:36.467 に答える