2

C#とJavaを使用して同じデータを暗号化しようとしています。データが7バイトを超える場合、JavaとC#の暗号化された値は同一ではありません。

  • 入力1:Java
    出力:FrOzOp / 2Io8 =
    C#出力:FrOzOp / 2Io8 =

  • 入力2:abc
    j:H9A / ahl8K7I =
    c#:H9A / ahl8K7I =

  • 入力3:aaaaaaaa問題
    j:Gxl7e0aWPd7j6l7uIEuMxA ==
    c#:Gxl7e0aWPd7sf1xR6hK4VQ ==

これがC#とJavaメソッドの実装です。
C#コード:

public String saltTxt = "12345678";
public String Encrypt(String txt)
{
        byte[] data = Encrypt(Encoding.UTF8.GetBytes(txt));
        
        DESCryptoServiceProvider alg = new DESCryptoServiceProvider();

        alg.Key = Encoding.UTF8.GetBytes(saltTxt.ToCharArray(), 0, cprovider.KeySize / 8);
        alg.IV = new byte[8];

        MemoryStream ms = new MemoryStream();
        CryptoStream stem = new CryptoStream( ms, cprovider.CreateEncryptor(),CryptoStreamMode.Write);

        stem.Write(txt, 0, txt.Length);
        stem.FlushFinalBlock();

        data = ms.ToArray();
        
        return Convert.ToBase64String(data);
 }

Javaコード:

public String saltTxt = "12345678";
public String Encrypt(String str) {
    try {
        KeySpec myKey = new DESKeySpec(saltTxt.getBytes("UTF8"));
        SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(myKey);
        Cipher ecipher = Cipher.getInstance("DES");
        ecipher.init(Cipher.ENCRYPT_MODE, key);

        byte[] data = str.getBytes("UTF8");

        byte[] crypt = ecipher.doFinal(data);
        
        return new BASE64Encoder().encode(crypt);
    } catch (Exception ex) {
    }

    return null;
} 

なぜそれが期待どおりに機能しないのか、何か考えはありますか?

4

3 に答える 3

9

問題はmode暗号化にありました。

SunJCEプロバイダーはECB、デフォルトモードとして、およびPKCS5PaddingDES、DES-EDE、およびBlowfish暗号のデフォルトのパディングスキームとして使用します。(JCA Doc

.Net、対称アルゴリズムのデフォルトの動作モードはでCipherMode.CBCあり、デフォルトのパディングはPaddingMode.PKCS7です。(msdn..SymmetricAlgorithm

次の変更で問題が解決します。

// in C# 
DESCryptoServiceProvider alg = new DESCryptoServiceProvider();
alg.Mode = CipherMode.ECB;  // specified 

また

// in java
chiper = Cipher.getInstance("DES/CBC/PKCS5Padding");

両側で変更しないでください。

于 2012-10-21T07:53:48.330 に答える
1

おそらく、ISO 10126のパディングが表示されています。これは、平文にランダムなバイトを追加して、ブロックサイズの倍数まで埋めます。
この動作は仕様によるものです。

于 2012-10-15T11:34:19.257 に答える
0

以下のコード(Java / Android)は私のために機能します。C#でも同じアプローチを使用しました。

public static String Cripto(String Password)
{
    String PasswordCripto = "";
    try
    {
        String encryptionKey = "anyEncryptionString";
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(encryptionKey.getBytes("UTF-8"), 0, encryptionKey.length());
        byte[] encryptionKeyBytes = messageDigest.digest();

        SecretKeySpec Key = new SecretKeySpec(encryptionKeyBytes,"DESede");
        Cipher cipher = Cipher.getInstance("DESEDE/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, Key);
        byte[] encryptedBytes = cipher.doFinal(Password.getBytes("UTF-8"));

        PasswordCripto = new String(Base64.encode(encryptedBytes, Base64.DEFAULT), "UTF-8");
    } catch(Exception e) { }
    return PasswordCripto ;
}
于 2015-01-23T23:25:17.983 に答える