72485
暗号化、PHPを勉強しています。  
vb.netで暗号化したデータをPHPで復号しようとしていますが、うまくいきません。

vb.netのプログラムは以下です。(コードが長いため参考サイトのリンクで失礼します)

[ＶＢめも-文字列暗号化](http://katsune.cocolog-nifty.com/blog/2009/05/--b8cd.html)

以下の点がわかりません。

・暗号化方式はDESになるのか  
・vb.netでは$ivにバイト配列が入るようだがPHPでは何を指定すればよいのか

何かヒントやアドバイスなどいただけないでしょうか。

試しているコードは以下です。

```

    <?php
    
    $data = "string";
    $method = "DES";
    $key = "key";
    $options = 0;
    
    $ivLength = openssl_cipher_iv_length($method);
    $iv = '8文字が入る？';
    // encrypt
    $enc = openssl_encrypt($data, $method, $key, $options,$iv);
    // decrypt
    $dec = openssl_decrypt($enc, $method, $key, $options,$iv;
    
    echo "plain: ".$data." encrypted: ".$enc." decrypted: ".$dec;
    
```
CC BY-SA 4.0
2020-12-06T16:19:07.130
72461
2020-12-07T12:10:54.973
2020-12-07T01:17:11.343
3060
43010
question
php vb.net
vb.netで暗号化、PHPで復号する
暗号化を行うにはアルゴリズムが強調されていますが、可変長データを扱うためには、何らかブロック単位で処理を行う必要があるため、[暗号利用モード](https://ja.wikipedia.org/wiki/%E6%9A%97%E5%8F%B7%E5%88%A9%E7%94%A8%E3%83%A2%E3%83%BC%E3%83%89)を選択する必要があります。またブロック単位で処理を行うと末尾に端数バイトが発生するため、そこを埋める[Paddingモード](https://en.wikipedia.org/wiki/Padding_\(cryptography\))も選択する必要があります。  
結局、

  * 暗号アルゴリズム 
    * キー
    * 初期ベクター
  * 暗号利用モード
  * Paddingモード

を一致させる必要があります。VB.NETとPHPとで暗号化・復号を行うのであれば、それぞれを一致させるようにコードで指定してください。

で、[VB.NETのDESCryptoServiceProviderクラス](https://docs.microsoft.com/ja-
jp/dotnet/api/system.security.cryptography.descryptoserviceprovider?view=net-5.0)であれば、

  * Keyプロパティ
  * IVプロパティ
  * Modeプロパティ
  * Paddingプロパティ  
を使い、[phpのopenssl_decrypt関数](https://www.php.net/manual/ja/function.openssl-
decrypt.php)であれば、

  * key引数
  * iv引数
  * method引数
  * options引数  
を使うようです。
CC BY-SA 4.0
2020-12-07T01:12:53.123
72463
2020-12-07T01:12:53.123
4236
72461
answer
> ・暗号化方式はDESになるのか

`openssl_encrypt`の第二引数のことでしたら、`openssl_get_cipher_methods()`が返すリストまたは`openssl
enc -list`コマンドが返すリストから選択する必要があります。今回の例だと`des`または`des-cbc`になると思います。

> ・vb.netでは$ivにバイト配列が入るようだがPHPでは何を指定すればよいのか

PHPはバイト配列は文字列型で扱います。VB.netでいうところの`{0, 1, 2}`は

```

    "\x00\x01\x02"
    
```

になります。

> $key = "key";

openssl_encryptに渡す`key`はパスワードではありません。暗号アルゴリズムごとに決まっている長さのデータである必要があります。

元のサイトのコードでは、これをごにょごにょするコードがありますが、あなたのコードにはそれがありません。

パッと見で気づいた「うまくいかない」理由になりそうなところはそのあたりですが、もっと手前の話として、元のサイトのコードは10年前に書かれたことを差し引いても十分に質が低いもので、参考にすべきではありません。

  * 10年前の基準でもDESは使うべきではない
  * 鍵やIVの意味を理解していない(ので、「パスワード」を自力でごにょごにょしている)

暗号を扱うのであれば、暗号技術入門(ISBN
978-4-7973-8222-8)を一読されることをお勧めします。これを読めばパッとコードが書けるようになる、というものではないですが、ドキュメントやリファレンスを読むためには基礎知識が必要です。
CC BY-SA 4.0
2020-12-07T12:10:54.973
72485
2020-12-07T12:10:54.973
5793
72461
answer