C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: 異なるプログラム間での文字列復号化処理について


(過去ログ 133 を表示中)

[トピック内 22 記事 (1 - 20 表示)]  << 0 | 1 >>

■78391 / inTopicNo.1)  異なるプログラム間での文字列復号化処理について
  
□投稿者/ リュウ (1回)-(2016/01/12(Tue) 14:14:49)

分類:[.NET 全般] 

初めまして。

今、JAVASCRIPTのDEST.js、BASE64.jsで暗号化した文字列を、VB.NETでDOBONさんや他のサイトの復号化処理を見て実際に試したところ、「データが正しくありません。」や「パディングは無効なので、削除できません。」というエラーが出てしまいます。
原因を確認したところ、キーやパスワードが異なるとか書かれてあったので、それで、VB.NET用の暗号化処理でどういう文字列が形成されるか調べたところ、JAVASCRIPTで生成した文字列とは異なる文字列が返却されてしまいました。
言語間でアルゴリズムが異なり文字列の生成も異なってくるのでしょうか?
暗号化はVB.NET側でしたものを複合化しないといけないのでしょうか?
すみませんが、どなたか教えていただきたいです。また、変換方法のサンプル等あればお教え願いたいです。
宜しくお願いします。
引用返信 編集キー/
■78392 / inTopicNo.2)  Re[1]: 異なるプログラム間での文字列復号化処理について
□投稿者/ Hongliang (394回)-(2016/01/12(Tue) 14:48:23)
DEST.jsとかいうのが見つかりませんでしたけど。

同じ暗号化アルゴリズムで、同じパラメータを使って暗号化すれば、結果は同じになるはずです。
必要なパラメータは結構多いですけど。
たとえばDESなどの秘密鍵暗号アルゴリズムで同じ結果を得ようとする場合、
共有鍵、初期ベクタ(IV)、パディング方法、etc...要は
https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.descryptoserviceprovider.aspx
のプロパティほぼ全部(LegalSize系以外)が一致していなければなりません。
LL系の言語の場合文字列を直接パスワードや暗号化対象にすることも多いような気がしますが、文字列であればそれをどうバイナリに変換しているかも重要です。
引用返信 編集キー/
■78393 / inTopicNo.3)  Re[1]: 異なるプログラム間での文字列復号化処理について
□投稿者/ 774RR (366回)-(2016/01/12(Tue) 14:54:27)
base64 は暗号ではないんで暗号とか復号とか呼ぶのは不適切なのでは・・・単純変換だし。
base64 の仕様として末尾が正しくパディングされてないと元文字列に変換できないよ。
正しく実装されていれば言語は問わないっす

それとも base64 ではなくて真に暗号?

引用返信 編集キー/
■78395 / inTopicNo.4)  Re[2]: 異なるプログラム間での文字列復号化処理について
□投稿者/ リュウ (2回)-(2016/01/12(Tue) 15:26:34)
No78393 (774RR さん) に返信
> base64 は暗号ではないんで暗号とか復号とか呼ぶのは不適切なのでは・・・単純変換だし。
> base64 の仕様として末尾が正しくパディングされてないと元文字列に変換できないよ。
> 正しく実装されていれば言語は問わないっす
>
> それとも base64 ではなくて真に暗号?
>

すみません、BASE64というよりDESの方です。申し訳ありませんでした。説明足りずで。
やはりパディングですか。
言語は問わないんですね。
引用返信 編集キー/
■78396 / inTopicNo.5)  Re[2]: 異なるプログラム間での文字列復号化処理について
□投稿者/ リュウ (3回)-(2016/01/12(Tue) 15:29:30)
No78392 (Hongliang さん) に返信
> DEST.jsとかいうのが見つかりませんでしたけど。
>
> 同じ暗号化アルゴリズムで、同じパラメータを使って暗号化すれば、結果は同じになるはずです。
> 必要なパラメータは結構多いですけど。
> たとえばDESなどの秘密鍵暗号アルゴリズムで同じ結果を得ようとする場合、
> 共有鍵、初期ベクタ(IV)、パディング方法、etc...要は
> https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.descryptoserviceprovider.aspx
> のプロパティほぼ全部(LegalSize系以外)が一致していなければなりません。
> LL系の言語の場合文字列を直接パスワードや暗号化対象にすることも多いような気がしますが、文字列であればそれをどうバイナリに変換しているかも重要です。

大変申し訳ありませんでした。DES.jsと呼ばれるものです。上のURLを参考にさせていただきますm(__)mそうなんですね。
ありがとうございます。
引用返信 編集キー/
■78397 / inTopicNo.6)  Re[1]: 異なるプログラム間での文字列復号化処理について
□投稿者/ 魔界の仮面弁士 (621回)-(2016/01/12(Tue) 15:33:51)
No78391 (リュウ さん) に返信
> 原因を確認したところ、キーやパスワードが異なるとか書かれてあったので、
それは Base64 の方ではなく、暗号化処理の方ですね。
DEST.js は使ったことが無いので分かりません…。

# 暗号化系なら Crypto とか Cryptographic という語を良く見かけますが、
# DEST って何の略だろう…。destination かな?
# DES とか TripleDES ではないみたいだし。



> 「データが正しくありません。」や「パディングは無効なので、削除できません。」というエラーが出てしまいます。
Base64 の処理対象外のデータが含まれているか、
またはパディング部(末尾の「=」)の数がおかしいのでしょう。

Base64 には幾つかの派生パターンがありますが、
基本的には「3 バイトを 4 文字で表現」する 24 bit 単位の変換法則であり、
データのバイト数が 3 の倍数でない場合、『パディング』が入ります。

※Base64 の発生実装では、パディングが省略されるものもありますし、
 あるいは HttpServerUtility.UrlTokenEncode のように、末尾に
 パディング数を追加付与するような実装もありますけれどね。



> 言語間でアルゴリズムが異なり文字列の生成も異なってくるのでしょうか?
電卓とソロバンで、掛け算の結果が左右されることが無いのと同様、
アルゴリズムが一緒なら、どんな言語で実装しようとも、結果は常に同一です。

さしあたり、CBC モードなラインダール系の暗号アルゴリズム
(いわゆる AES)を使えば、処理系を問わず同じ結果が得られると思います。

.NET Framework だと、System.Security.Cryptography 名前空間ですね。
https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.aspx



> 変換方法のサンプル等あればお教え願いたいです。
.NET 側のサンプルとして。

http://dobon.net/vb/dotnet/string/encryptfile.html
http://dobon.net/vb/dotnet/string/encryptstring.html


DEST.js で暗号化した場合と、VB.NET から暗号化した場合とで、
結果が同じになるか比較にしてみては如何でしょう。
(もちろん、Key と IV が同じになるようにせねばなりません)



重要なのは、「共有鍵(Key)」と「初期化ベクトル(IV)」が、
暗号化時と複合化時で、同じものが渡されねばならないということです。

(※注1) 処理系によって、常時同じ Key を使いまわす実装と、
 暗号化のたびに異なる Key を用意する実装とがあります。


(※注2) 毎回異なるバイナリが生成されるよう、IV には十分にランダムなデータが
 使われることが多いです。そしてこの暗号化に使われる IV は、
  (a)「IV を、暗号化/複合化処理の両方に、明示的に渡す必要があるケース」
  (b)「IV を、複合化処理の際だけ渡すケース」
  (c)「IV を暗号化時にも複合化時にも指定しないケース」
 の 3 パターンがあります。

 (a) の場合、IV は自身で生成しなければなりません。

 (b) の場合、暗号化時の IV は自動生成されます。それを受け取って複合化時に使います。

 (c) の場合、暗号化電文の中に IV が埋め込まれています。この場合には、
  VB.NET で復号する前に、電文中の IV と暗号データ部を切り出す作業が必要です。
引用返信 編集キー/
■78398 / inTopicNo.7)  Re[2]: 異なるプログラム間での文字列復号化処理について
□投稿者/ リュウ (4回)-(2016/01/12(Tue) 15:41:12)
丁寧なご説明ありがとうございますm(__)m
大変申し訳ありませんでした。DES.jsです。
DES方式の暗号化です。
それを復号化しようとしているのですが、IVの部分を指定していなかったです。
IVの部分を指定するサンプルが見かけられなかったので。自分の見落としかもしれませんが。
DES.jsではdes.decryptメソッドで
以下の引数になっており
des.decrypt( cipherText, key [, mode [, paddingChar]] );
JAVASCRIPT側では第3の引数も渡しておりました。これも一致させないといけないのですね?

No78397 (魔界の仮面弁士 さん) に返信
> ■No78391 (リュウ さん) に返信
>>原因を確認したところ、キーやパスワードが異なるとか書かれてあったので、
> それは Base64 の方ではなく、暗号化処理の方ですね。
> DEST.js は使ったことが無いので分かりません…。
>
> # 暗号化系なら Crypto とか Cryptographic という語を良く見かけますが、
> # DEST って何の略だろう…。destination かな?
> # DES とか TripleDES ではないみたいだし。
>
>
>
>>「データが正しくありません。」や「パディングは無効なので、削除できません。」というエラーが出てしまいます。
> Base64 の処理対象外のデータが含まれているか、
> またはパディング部(末尾の「=」)の数がおかしいのでしょう。
>
> Base64 には幾つかの派生パターンがありますが、
> 基本的には「3 バイトを 4 文字で表現」する 24 bit 単位の変換法則であり、
> データのバイト数が 3 の倍数でない場合、『パディング』が入ります。
>
> ※Base64 の発生実装では、パディングが省略されるものもありますし、
>  あるいは HttpServerUtility.UrlTokenEncode のように、末尾に
>  パディング数を追加付与するような実装もありますけれどね。
>
>
>
>>言語間でアルゴリズムが異なり文字列の生成も異なってくるのでしょうか?
> 電卓とソロバンで、掛け算の結果が左右されることが無いのと同様、
> アルゴリズムが一緒なら、どんな言語で実装しようとも、結果は常に同一です。
>
> さしあたり、CBC モードなラインダール系の暗号アルゴリズム
> (いわゆる AES)を使えば、処理系を問わず同じ結果が得られると思います。
>
> .NET Framework だと、System.Security.Cryptography 名前空間ですね。
> https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.aspx
>
>
>
>>変換方法のサンプル等あればお教え願いたいです。
> .NET 側のサンプルとして。
>
> http://dobon.net/vb/dotnet/string/encryptfile.html
> http://dobon.net/vb/dotnet/string/encryptstring.html
>
>
> DEST.js で暗号化した場合と、VB.NET から暗号化した場合とで、
> 結果が同じになるか比較にしてみては如何でしょう。
> (もちろん、Key と IV が同じになるようにせねばなりません)
>
>
>
> 重要なのは、「共有鍵(Key)」と「初期化ベクトル(IV)」が、
> 暗号化時と複合化時で、同じものが渡されねばならないということです。
>
> (※注1) 処理系によって、常時同じ Key を使いまわす実装と、
>  暗号化のたびに異なる Key を用意する実装とがあります。
>
>
> (※注2) 毎回異なるバイナリが生成されるよう、IV には十分にランダムなデータが
>  使われることが多いです。そしてこの暗号化に使われる IV は、
>   (a)「IV を、暗号化/複合化処理の両方に、明示的に渡す必要があるケース」
>   (b)「IV を、複合化処理の際だけ渡すケース」
>   (c)「IV を暗号化時にも複合化時にも指定しないケース」
>  の 3 パターンがあります。
>
>  (a) の場合、IV は自身で生成しなければなりません。
>
>  (b) の場合、暗号化時の IV は自動生成されます。それを受け取って複合化時に使います。
>
>  (c) の場合、暗号化電文の中に IV が埋め込まれています。この場合には、
>   VB.NET で復号する前に、電文中の IV と暗号データ部を切り出す作業が必要です。
引用返信 編集キー/
■78399 / inTopicNo.8)  Re[3]: 異なるプログラム間での文字列復号化処理について
□投稿者/ リュウ (5回)-(2016/01/12(Tue) 15:43:38)
以下はIVが無いおかげで異なっていました。IVになりうる文字列っぽいのがあるんですが
それが該当するのかわかりませんでした。また、どこで、設定するのか?

> DEST.js で暗号化した場合と、VB.NET から暗号化した場合とで、
> 結果が同じになるか比較にしてみては如何でしょう。
> (もちろん、Key と IV が同じになるようにせねばなりません)


No78398 (リュウ さん) に返信
> 丁寧なご説明ありがとうございますm(__)m
> 大変申し訳ありませんでした。DES.jsです。
> DES方式の暗号化です。
> それを復号化しようとしているのですが、IVの部分を指定していなかったです。
> IVの部分を指定するサンプルが見かけられなかったので。自分の見落としかもしれませんが。
> DES.jsではdes.decryptメソッドで
> 以下の引数になっており
> des.decrypt( cipherText, key [, mode [, paddingChar]] );
> JAVASCRIPT側では第3の引数も渡しておりました。これも一致させないといけないのですね?
>
> ■No78397 (魔界の仮面弁士 さん) に返信
>>■No78391 (リュウ さん) に返信
> >>原因を確認したところ、キーやパスワードが異なるとか書かれてあったので、
>>それは Base64 の方ではなく、暗号化処理の方ですね。
>>DEST.js は使ったことが無いので分かりません…。
>>
>># 暗号化系なら Crypto とか Cryptographic という語を良く見かけますが、
>># DEST って何の略だろう…。destination かな?
>># DES とか TripleDES ではないみたいだし。
>>
>>
>>
> >>「データが正しくありません。」や「パディングは無効なので、削除できません。」というエラーが出てしまいます。
>>Base64 の処理対象外のデータが含まれているか、
>>またはパディング部(末尾の「=」)の数がおかしいのでしょう。
>>
>>Base64 には幾つかの派生パターンがありますが、
>>基本的には「3 バイトを 4 文字で表現」する 24 bit 単位の変換法則であり、
>>データのバイト数が 3 の倍数でない場合、『パディング』が入ります。
>>
>>※Base64 の発生実装では、パディングが省略されるものもありますし、
>> あるいは HttpServerUtility.UrlTokenEncode のように、末尾に
>> パディング数を追加付与するような実装もありますけれどね。
>>
>>
>>
> >>言語間でアルゴリズムが異なり文字列の生成も異なってくるのでしょうか?
>>電卓とソロバンで、掛け算の結果が左右されることが無いのと同様、
>>アルゴリズムが一緒なら、どんな言語で実装しようとも、結果は常に同一です。
>>
>>さしあたり、CBC モードなラインダール系の暗号アルゴリズム
>>(いわゆる AES)を使えば、処理系を問わず同じ結果が得られると思います。
>>
>>.NET Framework だと、System.Security.Cryptography 名前空間ですね。
>>https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.aspx
>>
>>
>>
> >>変換方法のサンプル等あればお教え願いたいです。
>>.NET 側のサンプルとして。
>>
>>http://dobon.net/vb/dotnet/string/encryptfile.html
>>http://dobon.net/vb/dotnet/string/encryptstring.html
>>
>>
>>DEST.js で暗号化した場合と、VB.NET から暗号化した場合とで、
>>結果が同じになるか比較にしてみては如何でしょう。
>>(もちろん、Key と IV が同じになるようにせねばなりません)
>>
>>
>>
>>重要なのは、「共有鍵(Key)」と「初期化ベクトル(IV)」が、
>>暗号化時と複合化時で、同じものが渡されねばならないということです。
>>
>>(※注1) 処理系によって、常時同じ Key を使いまわす実装と、
>> 暗号化のたびに異なる Key を用意する実装とがあります。
>>
>>
>>(※注2) 毎回異なるバイナリが生成されるよう、IV には十分にランダムなデータが
>> 使われることが多いです。そしてこの暗号化に使われる IV は、
>>  (a)「IV を、暗号化/複合化処理の両方に、明示的に渡す必要があるケース」
>>  (b)「IV を、複合化処理の際だけ渡すケース」
>>  (c)「IV を暗号化時にも複合化時にも指定しないケース」
>> の 3 パターンがあります。
>>
>> (a) の場合、IV は自身で生成しなければなりません。
>>
>> (b) の場合、暗号化時の IV は自動生成されます。それを受け取って複合化時に使います。
>>
>> (c) の場合、暗号化電文の中に IV が埋め込まれています。この場合には、
>>  VB.NET で復号する前に、電文中の IV と暗号データ部を切り出す作業が必要です。
引用返信 編集キー/
■78401 / inTopicNo.9)  Re[4]: 異なるプログラム間での文字列復号化処理について
□投稿者/ リュウ (6回)-(2016/01/12(Tue) 16:06:35)
すみませんm(__)mくれくれ君になってしまいまして(TT)

No78399 (リュウ さん) に返信
> 以下はIVが無いおかげで異なっていました。IVになりうる文字列っぽいのがあるんですが
> それが該当するのかわかりませんでした。また、どこで、設定するのか?
>
>>DEST.js で暗号化した場合と、VB.NET から暗号化した場合とで、
>>結果が同じになるか比較にしてみては如何でしょう。
>>(もちろん、Key と IV が同じになるようにせねばなりません)
>
>
> ■No78398 (リュウ さん) に返信
>>丁寧なご説明ありがとうございますm(__)m
>>大変申し訳ありませんでした。DES.jsです。
>>DES方式の暗号化です。
>>それを復号化しようとしているのですが、IVの部分を指定していなかったです。
>>IVの部分を指定するサンプルが見かけられなかったので。自分の見落としかもしれませんが。
>>DES.jsではdes.decryptメソッドで
>>以下の引数になっており
>>des.decrypt( cipherText, key [, mode [, paddingChar]] );
>>JAVASCRIPT側では第3の引数も渡しておりました。これも一致させないといけないのですね?
>>
>>■No78397 (魔界の仮面弁士 さん) に返信
> >>■No78391 (リュウ さん) に返信
>>>>原因を確認したところ、キーやパスワードが異なるとか書かれてあったので、
> >>それは Base64 の方ではなく、暗号化処理の方ですね。
> >>DEST.js は使ったことが無いので分かりません…。
> >>
> >># 暗号化系なら Crypto とか Cryptographic という語を良く見かけますが、
> >># DEST って何の略だろう…。destination かな?
> >># DES とか TripleDES ではないみたいだし。
> >>
> >>
> >>
>>>>「データが正しくありません。」や「パディングは無効なので、削除できません。」というエラーが出てしまいます。
> >>Base64 の処理対象外のデータが含まれているか、
> >>またはパディング部(末尾の「=」)の数がおかしいのでしょう。
> >>
> >>Base64 には幾つかの派生パターンがありますが、
> >>基本的には「3 バイトを 4 文字で表現」する 24 bit 単位の変換法則であり、
> >>データのバイト数が 3 の倍数でない場合、『パディング』が入ります。
> >>
> >>※Base64 の発生実装では、パディングが省略されるものもありますし、
> >> あるいは HttpServerUtility.UrlTokenEncode のように、末尾に
> >> パディング数を追加付与するような実装もありますけれどね。
> >>
> >>
> >>
>>>>言語間でアルゴリズムが異なり文字列の生成も異なってくるのでしょうか?
> >>電卓とソロバンで、掛け算の結果が左右されることが無いのと同様、
> >>アルゴリズムが一緒なら、どんな言語で実装しようとも、結果は常に同一です。
> >>
> >>さしあたり、CBC モードなラインダール系の暗号アルゴリズム
> >>(いわゆる AES)を使えば、処理系を問わず同じ結果が得られると思います。
> >>
> >>.NET Framework だと、System.Security.Cryptography 名前空間ですね。
> >>https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.aspx
> >>
> >>
> >>
>>>>変換方法のサンプル等あればお教え願いたいです。
> >>.NET 側のサンプルとして。
> >>
> >>http://dobon.net/vb/dotnet/string/encryptfile.html
> >>http://dobon.net/vb/dotnet/string/encryptstring.html
> >>
> >>
> >>DEST.js で暗号化した場合と、VB.NET から暗号化した場合とで、
> >>結果が同じになるか比較にしてみては如何でしょう。
> >>(もちろん、Key と IV が同じになるようにせねばなりません)
> >>
> >>
> >>
> >>重要なのは、「共有鍵(Key)」と「初期化ベクトル(IV)」が、
> >>暗号化時と複合化時で、同じものが渡されねばならないということです。
> >>
> >>(※注1) 処理系によって、常時同じ Key を使いまわす実装と、
> >> 暗号化のたびに異なる Key を用意する実装とがあります。
> >>
> >>
> >>(※注2) 毎回異なるバイナリが生成されるよう、IV には十分にランダムなデータが
> >> 使われることが多いです。そしてこの暗号化に使われる IV は、
> >>  (a)「IV を、暗号化/複合化処理の両方に、明示的に渡す必要があるケース」
> >>  (b)「IV を、複合化処理の際だけ渡すケース」
> >>  (c)「IV を暗号化時にも複合化時にも指定しないケース」
> >> の 3 パターンがあります。
> >>
> >> (a) の場合、IV は自身で生成しなければなりません。
> >>
> >> (b) の場合、暗号化時の IV は自動生成されます。それを受け取って複合化時に使います。
> >>
> >> (c) の場合、暗号化電文の中に IV が埋め込まれています。この場合には、
> >>  VB.NET で復号する前に、電文中の IV と暗号データ部を切り出す作業が必要です。
引用返信 編集キー/
■78402 / inTopicNo.10)  Re[5]: 異なるプログラム間での文字列復号化処理について
□投稿者/ Hongliang (395回)-(2016/01/12(Tue) 16:09:24)
> 以下はIVが無いおかげで異なっていました。IVになりうる文字列っぽいのがあるんですが
> それが該当するのかわかりませんでした。また、どこで、設定するのか?

お使いになっているDES.jsとやらを解析するしかないでしょう。
引用返信 編集キー/
■78403 / inTopicNo.11)  Re[6]: 異なるプログラム間での文字列復号化処理について
□投稿者/ リュウ (7回)-(2016/01/12(Tue) 16:14:45)
確かにそうですね・・・。見ているのですが、よく分からなくて(TT)

No78402 (Hongliang さん) に返信
>>以下はIVが無いおかげで異なっていました。IVになりうる文字列っぽいのがあるんですが
>>それが該当するのかわかりませんでした。また、どこで、設定するのか?
>
> お使いになっているDES.jsとやらを解析するしかないでしょう。
引用返信 編集キー/
■78404 / inTopicNo.12)  Re[3]: 異なるプログラム間での文字列復号化処理について
□投稿者/ 魔界の仮面弁士 (622回)-(2016/01/12(Tue) 16:39:13)
引用は適切に。全文引用は読みにくいです。


No78398 (リュウ さん) に返信
> DES方式の暗号化です。
3-DES ではなく、ただの DES なのですね?
http://e-words.jp/w/DES.html


> IVの部分を指定するサンプルが見かけられなかったので。自分の見落としかもしれませんが。
> DES.jsではdes.decryptメソッドで
その DES.js の入手先を教えては頂けないのでしょうか?
具体的な仕様が分からないと、こちらとしても答えにくいです。

# 典型的な エスパー回答パターン(泣


"JavaScript DES decrypt" で調べたら、こんなのがヒットしましたが、ファイル名が違うようで。
https://code.google.com/p/crypto-js/

"DES.js" だとこんなのがヒットしましたが、今度はメソッド名が違う…。
http://www.onicos.com/staff/iz/release/des_cbc.html

メソッド仕様からすると、これだろうか…?
http://user1.matsumoto.ne.jp/~goma/js/des.js


参考までに、VB.NET での DES 利用について。
https://support.microsoft.com/ja-jp/kb/301070
http://dobon.net/vb/bbs/log3-43/25936.html



> des.decrypt( cipherText, key [, mode [, paddingChar]] );
> JAVASCRIPT側では第3の引数も渡しておりました。これも一致させないといけないのですね?

その表記法からすると、第3引数は省略可能なようですね。
そのメソッドの仕様では、mode に何を渡すことになっていますか?


名前からすると、ブロック暗号の利用モードの事かな…と予想。
仮にそうなら、.NET の System.Security.Cryptography.CipherMode 相当のものなので、
CBC 相当の指定を行うのが良いでしょう。
(暗号利用モードでは無いかもしれませんが、仕様が分からないのでどうにもなりません)



> 以下はIVが無いおかげで異なっていました。

たとえば、.NET Framework における
 System.Security.Cryptography.DES クラス
 System.Security.Cryptography.DESCryptoServiceProvider クラス
の場合、
 ・クラスのインスタンスを生成した時点で、ランダムな IV が自動的に生成される。
 ・GenerateIV() メソッドで、新たな IV を自動生成することもできる。
 ・IV プロパティを通じて、自身で用意した初期化ベクトルを指定することもできる。
という仕様になっています。
お使いの DES.js でも、同じようなモノがあるのではないでしょうか。


> IVになりうる文字列っぽいのがあるんですが
> それが該当するのかわかりませんでした。

該当するかどうかを確認するために、JavaScript と VB.NET とで、
共に同じデータを暗号化してみては如何でしょうか。


同じデータ、同じKey、同じIVを指定すれば、JavaScript であれ VB.NET であれ、
結果は同じになるはずです。それがバイナリとして返されるのか、それとも
Base64 文字列として返されるのかといった違いはあるかもしれませんが。


No78402 (Hongliang さん) に返信
> お使いになっているDES.jsとやらを解析するしかないでしょう。

ソースそのものは圧縮・難読化されているケースもあるので、
最初に読むべきは、js そのものではなく、その仕様説明でしょうね。
引用返信 編集キー/
■78405 / inTopicNo.13)  Re[4]: 異なるプログラム間での文字列復号化処理について
□投稿者/ 774RR (367回)-(2016/01/12(Tue) 16:50:35)
っていうか DES なんだったら単方向ハッシュなわけで「復号」ができるはずがないので
なんか勘違いがあるような気のせいが・・・

ってかいまどき DES なんか使っちゃダメ(20世紀の時点で既に破られている)
引用返信 編集キー/
■78407 / inTopicNo.14)  Re[5]: 異なるプログラム間での文字列復号化処理について
□投稿者/ Hongliang (396回)-(2016/01/12(Tue) 16:54:58)
> っていうか DES なんだったら単方向ハッシュなわけで「復号」ができるはずがないので
ん?
DESは共通鍵暗号ですよ?
引用返信 編集キー/
■78408 / inTopicNo.15)  Re[5]: 異なるプログラム間での文字列復号化処理について
□投稿者/ 魔界の仮面弁士 (623回)-(2016/01/12(Tue) 17:06:51)
No78405 (774RR さん) に返信
> っていうか DES なんだったら単方向ハッシュなわけで「復号」ができるはずがないので
MD5 等は単方向ハッシュですけど、DES は復号できますよ。

というか、復号できなかったら 3-DES が作れるわけが無いわけで。


> ってかいまどき DES なんか使っちゃダメ(20世紀の時点で既に破られている)

ってことで、個人的には No78397 に書いたように

>> さしあたり、CBC モードなラインダール系の暗号アルゴリズム
>> (いわゆる AES)を使えば、処理系を問わず同じ結果が得られると思います。

だったり。
引用返信 編集キー/
■78409 / inTopicNo.16)  Re[4]: 異なるプログラム間での文字列復号化処理について
□投稿者/ リュウ (8回)-(2016/01/12(Tue) 17:11:03)
丁寧なご回答再度ありがとうございます。

> 引用は適切に。全文引用は読みにくいです。

気を付けますm(__)m

はい、ただの DESです。

> # 典型的な エスパー回答パターン(泣

すみません、ソースは会社で用意されたものなので、部分的にしか見せられない
状態です(TT)

> 名前からすると、ブロック暗号の利用モードの事かな…と予想。
> 仮にそうなら、.NET の System.Security.Cryptography.CipherMode 相当のものなので、
> CBC 相当の指定を行うのが良いでしょう。
> (暗号利用モードでは無いかもしれませんが、仕様が分からないのでどうにもなりません)

そうですか。うーん、試してみます。
仕様説明書が無いのでなんとやら(TT)
引用返信 編集キー/
■78415 / inTopicNo.17)  Re[5]: 異なるプログラム間での文字列復号化処理について
□投稿者/ 魔界の仮面弁士 (624回)-(2016/01/12(Tue) 19:28:29)
No78409 (リュウ さん) に返信
> 仕様説明書が無いのでなんとやら(TT)
その js コードはどこから入手したものですか?
出所やライセンスは明らかにしておくべきかと思いますよ。(^^;


仕方ないので、エスパー回答を継続。


> すみません、ソースは会社で用意されたものなので、部分的にしか見せられない
> 状態です(TT)

もちろん、部分的で良いですよ。

そもそも暗号化アルゴリズムが DES だとすれば、
そこに渡すべき情報は、

 (1) 元のバイナリ(あるいは文字列かもしれませんが)
 (2) 共通鍵(パスワードと呼ばれる事もあります)
 (3) 初期化ベクトル(意識させないよう内包されている実装もあります)
 (4) 暗号化ブロックモード(一般的には CBC モード)

ぐらいしか無いでしょうし。
あとは…パディングモードとか、エンコーディングぐらい?


なお、上記の幾つかのパラメーターについては、コードから指定するのではなく、
常に固定値が使われるケースや、あるいは設定ファイル等で指定するように
なっているライブラリ実装も存在します。

しかし、現状の実装がどのパターンに該当するのかは、
掲示板を見ている我々には分からないことですけれども。




たとえば、仮に
 (1) "Ryu" の 3 バイト (52, 79, 75)
 (2) "Password" の 8 バイト (50, 61, 73, 73, 77, 6F, 72, 64)
 (3) "20160112" の 8 バイト (32, 30, 31, 36, 30, 31, 31, 32)
 (4) CBC モード
だとすれば、暗号化した結果は必ず
 82, 73, B0, 0C, 2F, A5, E2, 4B
という 8 バイトのバイナリになります。
これを BASE64 変換すれば
 『gnOwDC+l4ks=』
ですね。



ただし No78397 の末尾に書いた 注2-C な実装のライブラリだった場合、
IV がこのバイナリの先頭(または末尾など)に付与されて、
 32, 30, 31, 36, 30, 31, 31, 32, 82, 73, B0, 0C, 2F, A5, E2, 4B
という 16 バイトのバイナリとして返却する処理系もあります。
この場合の Base64 は
 『MjAxNjAxMTKCc7AML6XiSw==』
となるはずです。
引用返信 編集キー/
■78417 / inTopicNo.18)  Re[6]: 異なるプログラム間での文字列復号化処理について
□投稿者/ 魔界の仮面弁士 (625回)-(2016/01/12(Tue) 22:11:59)
No78415 (魔界の仮面弁士) に追記
> 仕方ないので、エスパー回答を継続。

テストコードを書いてみました。まずは VB.NET 版。


検証用のデータとして

>  (1) "Ryu" の 3 バイト (52, 79, 75)
>  (2) "Password" の 8 バイト (50, 61, 73, 73, 77, 6F, 72, 64)
>  (3) "20160112" の 8 バイト (32, 30, 31, 36, 30, 31, 31, 32)
>  (4) CBC モード

を採用しています。この場合の処理結果は

>  82, 73, B0, 0C, 2F, A5, E2, 4B
>  『gnOwDC+l4ks=』

となれば成功ですね。



なお、DESCryptoServiceProvider クラスそのものは
バイナリデータの暗号化も可能なのですが、ここでは単純化するため、
パラメータとして文字列のみを受け付ける実装にしています。

また、パディングモードは、標準の PKCS#5 / PKCS#7 のままなので、
 元データ長が 1 バイトの場合 → 末尾に 7 つの 0x07 が付く
 元データ長が 2 バイトの場合 → 末尾に 6 つの 0x06 が付く
 元データ長が 3 バイトの場合 → 末尾に 5 つの 0x05 が付く ★今回はこれ
 元データ長が 4 バイトの場合 → 末尾に 4 つの 0x04 が付く
 元データ長が 5 バイトの場合 → 末尾に 3 つの 0x03 が付く
 元データ長が 6 バイトの場合 → 末尾に 2 つの 0x02 が付く
 元データ長が 7 バイトの場合 → 末尾に 1 つの 0x01 が付く
 元データ長が 8 バイトの場合 → 末尾に 8 つの 0x08 が付く
と加工してから暗号化されているはずです(この処理は自動的に行われます)。


Imports System
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text

Module Module1

    Sub Main()
        Dim cipher As String = Encrypt("Ryu", "Password", "20160112")
        Console.WriteLine(cipher)

        Dim result As String = Decrypt(cipher, "Password", "20160112")
        Console.WriteLine(result)

        Console.ReadKey()
    End Sub


    Function Encrypt(ByVal plainText As String, ByVal key8 As String, ByVal iv As String) As String
        Dim enc = Encoding.UTF8

        Dim binKey8() As Byte = enc.GetBytes(key8)
        Dim binIV8() As Byte = enc.GetBytes(iv)


        Dim result() As Byte
        Dim trans = New DESCryptoServiceProvider().CreateEncryptor(binKey8, binIV8)
        Using ms As New MemoryStream(), _
            crypt As New CryptoStream(ms, trans, CryptoStreamMode.Write)

            Dim binSrc() As Byte = enc.GetBytes(plainText)
            crypt.Write(binSrc, 0, binSrc.Length)
            crypt.FlushFinalBlock()

            result = ms.ToArray()
            crypt.Close()
        End Using

        Dim base64Str As String = Convert.ToBase64String(result)
        Return base64Str
    End Function

    Function Decrypt(ByVal base64Str As String, ByVal key8 As String, ByVal iv As String) As String
        Dim enc = Encoding.UTF8

        Dim cipherBinary() As Byte = Convert.FromBase64String(base64Str)
        Dim binKey8() As Byte = enc.GetBytes(key8)
        Dim binIV8() As Byte = enc.GetBytes(iv)

        Dim plainText As String

        Dim trans = New DESCryptoServiceProvider().CreateDecryptor(binKey8, binIV8)
        Using ms As New MemoryStream(cipherBinary), _
            crypt As New CryptoStream(ms, trans, CryptoStreamMode.Read), _
            reader As New StreamReader(crypt, Encoding.UTF8)

            crypt.Flush()
            plainText = reader.ReadToEnd()
            reader.Close()
        End Using

        Return plainText
    End Function

End Module

引用返信 編集キー/
■78418 / inTopicNo.19)  Re[6]: 異なるプログラム間での文字列復号化処理について
□投稿者/ 魔界の仮面弁士 (626回)-(2016/01/12(Tue) 22:15:29)
No78415 (魔界の仮面弁士) に追記
>  (1) "Ryu" の 3 バイト (52, 79, 75)
>  (2) "Password" の 8 バイト (50, 61, 73, 73, 77, 6F, 72, 64)
>  (3) "20160112" の 8 バイト (32, 30, 31, 36, 30, 31, 31, 32)
>  (4) CBC モード

次は JavaScript 版。

……と言っても、リュウさんがどのようなライブラリを使っているのか
分からないので、とりあえずここでは、No78404 の回答時に発掘した
>> メソッド仕様からすると、これだろうか…?
>> http://user1.matsumoto.ne.jp/~goma/js/des.js
を使っています。手元の Firefox と Chrome で動作確認。

この場合の実行結果は

>> No78397 の末尾に書いた 注2-C な実装のライブラリだった場合、

に相当するライブラリらしく、処理結果が(IV の長さの) 8 バイト増加して、

>  32, 30, 31, 36, 30, 31, 31, 32, 82, 73, B0, 0C, 2F, A5, E2, 4B
>  『MjAxNjAxMTKCc7AML6XiSw==』

になりました。


なお、このライブラリのパディングモードは、
 元データ長が 1 バイトの場合 → 末尾に 7 つの 0x05 が付く
 元データ長が 2 バイトの場合 → 末尾に 6 つの 0x05 が付く
 元データ長が 3 バイトの場合 → 末尾に 5 つの 0x05 が付く ★今回はこれ
 元データ長が 4 バイトの場合 → 末尾に 4 つの 0x05 が付く
 元データ長が 5 バイトの場合 → 末尾に 3 つの 0x05 が付く
 元データ長が 6 バイトの場合 → 末尾に 2 つの 0x05 が付く
 元データ長が 7 バイトの場合 → 末尾に 1 つの 0x05 が付く
 元データ長が 8 バイトの場合 → パディングなし
という実装のようです。引数指定で 0x05 以外も指定できるようですが、
バイナリデータの暗号化にはむかない実装ですね…。


# っていうかこれ、DESCryptoServiceProvider クラスに無いパディングモードだったりする。
# まぁ、今回の検証データは、"Ryu" という 3 バイトのデータだったので、運良く
# 「末尾に 5 つの 0x05 が付く」処理が行われているわけですが(汗)。


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Sample for bbs.wankuma.com #78391</title>
<script src="http://user1.matsumoto.ne.jp/~goma/js/des.js"></script>
</head>
<body>
<script>

function fnEncrypt()
{
  var plainText = "Ryu";

  var mode = "cbc";
  var key = "Password";
  var iv = "20160112";

  var result = des.encrypt( plainText, key, mode, iv );
  // このライブラリの場合、result の先頭 8 バイトに iv が付与されます

  // JavaScript には Base64 系の標準実装が無いので、
  // とりあえず btoa メソッドで代用しています(本来は不適切)
  var base64Str = window.btoa( result );

  document.getElementById("Result1").value = base64Str;
}


function fnDecrypt()
{
  var base64Str = document.getElementById("Result1").value;

  // 本来は atob ではなく、正しい Base64 実装に置き換えて下さい
  var cipherText = window.atob( base64Str );

  var mode = "cbc";
  var key = "Password";
  // IV を指定するパラメーターがありませんが、これは IV が
  // cipherText 内の先頭 8 バイトに埋め込まれているためです

  var result = des.decrypt( cipherText, key, mode );
  document.getElementById("Result2").value = result;
}
</script>
<p><input type="button" value="Encrypt" onclick="return fnEncrypt();"></p>
<p><input type="text" readonly="readonly" id="Result1" value=""></p>
<p><input type="button" value="Decrypt" onclick="return fnDecrypt();"></p>
<p><input type="text" readonly="readonly" id="Result2" value=""></p>
</body>
</html>

引用返信 編集キー/
■78419 / inTopicNo.20)  Re[6]: 異なるプログラム間での文字列復号化処理について
 
□投稿者/ 魔界の仮面弁士 (627回)-(2016/01/12(Tue) 22:16:40)
No78415 (魔界の仮面弁士) に追記
>  (1) "Ryu" の 3 バイト (52, 79, 75)
>  (2) "Password" の 8 バイト (50, 61, 73, 73, 77, 6F, 72, 64)
>  (3) "20160112" の 8 バイト (32, 30, 31, 36, 30, 31, 31, 32)
>  (4) CBC モード

最後は、VB.NET を使って、
> ただし No78397 の末尾に書いた 注2-C な実装のライブラリだった場合、
のパターンで実装した場合です。

結果は
>  32, 30, 31, 36, 30, 31, 31, 32, 82, 73, B0, 0C, 2F, A5, E2, 4B
>  『MjAxNjAxMTKCc7AML6XiSw==』
になるはず。


ついでに、標準の PaddingMode はあえて使わず、先の JavaScript 実装にあわせて、
0x05 で埋める実装にしてみました。元データが 3 バイトだと区別できないですけど。



Imports System
Imports System.Security.Cryptography
Imports System.IO
Imports System.Text

Module Module1

    Sub Main()
        Dim cipherWithIV As String = EncryptWithIV("Ryu", "Password", "20160112")
        Console.WriteLine(cipherWithIV)

        Dim result2 As String = DecryptWithIV(cipherWithIV, "Password")
        Console.WriteLine(result2)

        Console.ReadLine()
    End Sub

    Function EncryptWithIV(ByVal plainText As String, ByVal key8 As String, ByVal iv As String) As String
        Dim enc = Encoding.UTF8

        Dim binKey8() As Byte = enc.GetBytes(key8)
        Dim binIV8() As Byte = enc.GetBytes(iv)

        Dim des As New DESCryptoServiceProvider() With {.Key = binKey8, .IV = binIV8}
        des.Padding = PaddingMode.None  '自分でパディングする

        Dim result() As Byte
        Using ms As New MemoryStream(), _
            crypt As New CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write)

            Dim binSrc() As Byte = enc.GetBytes(plainText)

            'データ長が 8 の倍数バイトで無かった場合、パディングが必要です。
            Dim paddingLength = (8 - (binSrc.Length Mod 8)) And 7

            'パディング値としてここでは、固定値 0x05 を付与しています。
            '(元が文字列なので、元データに 0x05 なバイナリが含まれることは無いと仮定)
            Dim binSrcWithPadding = binSrc.Concat( _
                Enumerable.Repeat(Of Byte)(5, paddingLength)).ToArray()

            crypt.Write(binSrcWithPadding, 0, binSrcWithPadding.Length)
            crypt.FlushFinalBlock()

            'この実装では、先頭に IV を埋めて返しています
            result = binIV8.Concat(ms.ToArray()).ToArray()
            crypt.Close()
        End Using

        Dim base64Str As String = Convert.ToBase64String(result)
        Return base64Str
    End Function

    Function DecryptWithIV(ByVal base64Str As String, ByVal key8 As String) As String
        Dim enc = Encoding.UTF8

        Dim cipherBinary() As Byte = Convert.FromBase64String(base64Str)
        Dim binKey8() As Byte = enc.GetBytes(key8)

        '先頭8バイトから IV を抜き出します
        Dim binIV8() As Byte = cipherBinary.Take(8).ToArray()

        '9バイト目以降の暗号文本体を取り出します
        Dim binBody() As Byte = cipherBinary.Skip(8).ToArray()

        Dim des As New DESCryptoServiceProvider() With {.Key = binKey8, .IV = binIV8}
        des.Padding = PaddingMode.Zeros  '自分でパディングを処理

        Dim plainText As String
        Using ms As New MemoryStream(binBody), _
            crypt As New CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Read), _
            reader As New StreamReader(crypt, Encoding.UTF8)

            crypt.Flush()

            '末尾にパディングとして、0〜7 文字の 0x05 が
            '付与されていることがあるので、これらを(手抜き実装で)除去します
            plainText = reader.ReadToEnd().TrimEnd(ChrW(5))

            reader.Close()
        End Using

        Return plainText
    End Function
End Module

引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -