@IT会議室は、ITエンジニアに特化した質問・回答コミュニティ「QA@IT」に生まれ変わりました。ぜひご利用ください。
- PR -

javaで暗号化(文字列)をVB.NETで復号

投稿者投稿内容
アムオタ
会議室デビュー日: 2007/06/28
投稿数: 5
投稿日時: 2007-07-11 19:10
javaで暗号化(DES)した文字列を、VB.NETで復号しようとしますがうまくいきません。
データが不正ですと例外が発生してしまいます。
解決する方法はないでしょうか。
javaで暗号化(DES)した文字列を、VB.NETで復号する事が不可能なのでしょうか。
ご教授、お願いします。
(大雑把なコーディングで申し訳ありません。)


  ////←--java(暗号化)
  import java.security.*;
  import javax.crypto.*;
  import javax.crypto.spec.SecretKeySpec;
  
  public String doChiper() {
   // 暗号化する文字列
   String clearText = "01000";
   byte[] binary = clearText.getBytes("UTF-8");

   // 暗号化のキー
   byte[] key = ("ACFGJSEX").getBytes("UTF-8");
   // 暗号化の実行
   SecretKeySpec k = new SecretKeySpec(key, "DES");
   Cipher c = Cipher.getInstance("DES");
   c.init(Cipher.ENCRYPT_MODE, k);
   byte[] encrypted = c.doFinal(binary);

   String encryptedStr = new String(Hex.encodeHex(encrypted));
   return encryptedStr;
  }
  ////←--java


  ////←--VB.NET(復号)
  Imports System.Security.Cryptography
  Public Shared Function DesCryptyVB(ByVal encryptedStr As String) As String
   Dim source As Byte()
   Dim decrypted As Byte()
   Dim DesKey() As Byte

    source = Hex2Bytes(encryptedStr)←16進文字列をbyte配列に変換する
    
    ' DESで復号化するためのオブジェクト
    Dim des As New DESCryptoServiceProvider
    
    ' 鍵は64ビット(8バイト)のバイト配列である必要がある
    DesKey = Encoding.UTF8.GetBytes("ACFGJSEX")
    des.Key = DesKey
    
    ' 初期化ベクタ(暗号化と復号化の際には同じIVを必要とする)
    des.IV = DesKey
    
    ' Decryptorを作成する
    Dim transform As ICryptoTransform = des.CreateDecryptor()
    
    ' バイト配列を復号化する
    decrypted = transform.TransformFinalBlock(source, 0, source.Length)

    transform.Dispose()

    ' byte 配列を文字列に変換して表示します
    DesCryptyVB = Encoding.UTF8.GetString(decrypted)
  End Sub

  ' 16進文字列をバイト配列に変換
  Private Shared Function Hex2Bytes(ByVal source As String) As Byte()
    ' 2文字で1バイトなので2で割っておく
    Dim length As Integer = source.Length / 2
    Dim cnt As Integer
    Dim result() As Byte
    Try
     ' サイズ設定
     ReDim result(length - 1)

     ' 16進数を10進数に変換
     For cnt = 0 To length - 1
      result(cnt) = CByte("&H" & source.Substring(cnt * 2, 2))
     Next cnt
    Catch ex As Exception
     MsgBox(ex.Message.ToString(), MsgBoxStyle.OKOnly)
     Return Nothing
    End Try

   Return result
  End Function
  ////←--VB.NET
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2007-07-11 19:37
「JAVAで暗号化したものをVBで復号できないか」と問う前に、しなければならないことがたくさんあるとおもいます。

JAVAで復号できるか
文字列化にミスはないか
バイト化にミスはないか
VBで暗号化したものを復号できるか
nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-07-11 19:45
引用:

アムオタさんの書き込み (2007-07-11 19:10) より:
javaで暗号化(DES)した文字列を、VB.NETで復号する事が不可能なのでしょうか。


それができないならDESなんて規格は意味がないわけですが…。

まずは、java側の実装で暗号化したものをjava側の実装で復号できるか、
VB側の実装で暗号化したものをVB側の実装で復号できるか、
VB→javaはどうか、java→VBはどうかを確認したいと結論はでないでしょうね。
スフレ
ぬし
会議室デビュー日: 2005/05/27
投稿数: 281
お住まい・勤務地: 東京
投稿日時: 2007-07-11 20:12
JavaとVBで、ブロックモードとパディング方式も合わせる必要があります。
あと、DES で任意の8バイトが鍵に使えたかどうかも怪しいです。
IVに鍵そのものなんて入れてはいけません。

甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-07-12 10:03
まずはデバッガで、Javaのbyte[] encryptedの内容と、VB.NETのDim source As Byte() に格納されている内容が完璧に一致しているのか確認。続いてbyte[] keyとDim DesKey() As Byte が完璧に一致しているか確認。

こういう質問って提示しているコードの外でバグっていることが多いので確認。平文をBlockサイズの整数倍に拡張する処理や、切り捨てる処理が見当たらないことから、その辺の処理の問題の予感がする。
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2007-07-12 11:41
私のとこだとこんな感じになってました。どこから拾ったんだっけな(ぉ。
keyのところが任意の8バイトになってますので、そこは問題ないと思います。
コード:

Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
DESKeySpec keySpec = new DESKeySpec(key.getBytes(CHAR_CODE));
byte[] bytes = keySpec.getKey();
SecretKey secretKey = new SecretKeySpec(bytes, "DES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(ivec));
byte[] encoded = cipher.doFinal(plain);



[ メッセージ編集済み 編集者: mio 編集日時 2007-07-12 11:43 ]
アムオタ
会議室デビュー日: 2007/06/28
投稿数: 5
投稿日時: 2007-07-13 22:37
色々とご意見をいただきまして、ありがとうございました。
java側で暗号化する際のkeyとivを暗号化した文字列に付加することによって、
それをVB.NET側で分解して処理すればうまくいきました。

//←java
Key key = makeKey1(64);
// 暗号化
KeyGenerator kg = KeyGenerator.getInstance("DES");
Cipher c = Cipher.getInstance("DES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, key);
byte input[] = src.getBytes();
encrypted = c.doFinal(input);
byte dKey[] = key.getEncoded();
byte iv[] = c.getIV();
ret = new byte[dKey.length + iv.length + encrypted.length];
System.arraycopy(dKey, 0, ret, 0, dKey.length);
System.arraycopy(iv, 0, ret, dKey.length, iv.length);
System.arraycopy(encrypted, 0, ret, dKey.length + iv.length ,encrypted.length);
chiper = new String(Hex.encodeHex(ret));
return chiper;
//←java

//←VB.NET
'' 文字列を byte 配列に変換します
Dim source As Byte()
Dim decrypted As Byte()
Try
source = Hex2Bytes(sEnc)

' DESで復号化するためのオブジェクト
Dim des As New DESCryptoServiceProvider

' 鍵は64ビット(8バイト)のバイト配列である必要がある
'DesKey = Encoding.ASCII.GetBytes("ACFGJSEX")
des.Key = DesKey

' 初期化ベクタ(暗号化と復号化の際には同じIVを必要とする)
des.IV = DesIV

' Decryptorを作成する
Dim transform As ICryptoTransform = des.CreateDecryptor()

' バイト配列を復号化する
decrypted = transform.TransformFinalBlock(source, 0, source.Length)

transform.Dispose()

Catch ex As Exception
MsgBox(ex.Message.ToString(), MsgBoxStyle.OKOnly)
Exit Function
End Try

' byte 配列を文字列に変換して表示します
DesCryptyVB = Encoding.ASCII.GetString(decrypted)
//←VB.NET


いろいろとご意見ありがとうございました。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2007-07-13 23:02
素朴な疑問なんですが、その暗号化処理をいったいどんな事に使おうとしてるんでしょうか?

スキルアップ/キャリアアップ(JOB@IT)