0

文字列を受け取り、文字列のエンコードされた値を CAST-256 で返す関数を実装しようとしています。次のコードは、BoncyCastle の公式 Web ページ ( http://www.bouncycastle.org/specifications.html、ポイント 4.1) の例に従って実装したものです。

import org.bouncycastle.crypto.BufferedBlockCipher;
import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.engines.CAST6Engine;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Base64;


public class Test {

    static{
        Security.addProvider(new BouncyCastleProvider());
    }

    public static final String UTF8 = "utf-8";
    public static final String KEY = "CLp4j13gADa9AmRsqsXGJ";

    public static byte[] encrypt(String inputString) throws UnsupportedEncodingException {
        final BufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CAST6Engine());
        byte[] key = KEY.getBytes(UTF8);
        byte[] input = inputString.getBytes(UTF8);
        cipher.init(true, new KeyParameter(key));

        byte[] cipherText = new byte[cipher.getOutputSize(input.length)];

        int outputLen = cipher.processBytes(input, 0, input.length, cipherText, 0);
        try {
            cipher.doFinal(cipherText, outputLen);
        } catch (CryptoException ce) {
            System.err.println(ce);
           System.exit(1);
        }
        return cipherText;
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        final String toEncrypt = "hola";
        final String encrypted = new String(Base64.encode(test(toEncrypt)),UTF8);
        System.out.println(encrypted);
    }

}

しかし、コードを実行すると、

QUrYzMVlbx3OK6IKXWq1ng==

同じキーを使用してCAST-256でエンコードする場合( http://www.tools4noobs.com/online_tools/encrypt/holaが必要な場合はこちらを試してください)、取得する必要があります

w5nZSYEyA8HuPL5V0J29Yg==.

何が起こっている?なぜ間違った暗号化文字列を取得するのですか?

インターネットでそれを見つけるのにうんざりしていて、答えが見つかりませんでした。

4

2 に答える 2

0

これは実際にあなたの質問に答えるものではありませんが、いくつかの指針を提供します。

PHP のmcrypt(). 鍵の生成、エンコード/デコード、および暗号アルゴリズムが正確に一致していることを確認する必要があります。

キー

"CLp4j13gADa9AmRsqsXGJ".getBytes("UTF-8");

おそらく、キー ソース バイトを作成する正しい方法ではありません。ドキュメントmcrypt()、キーとデータが\0適切なサイズでない場合にパディングすることを示しているようです。あなたのメソッドは168ビットのキーを生成することに注意してください。これは有効なキーサイズではなく、Javaがそれに対して何をするのかわかりません。

アルゴリズム
暗号モードとパディングが同じであることを確認してください。mcrypt()ECB、CBC、その他を使用していますか?

エンコーディング
暗号は、文字列ではなくバイトで機能します。2 つの間の変換が Java と PHP で同じであることを確認してください。

https://www.rfc-editor.org/rfc/rfc2612#page-10のテスト ベクトルを使用した CAST6 の参照テストを次に示します。キー、暗号文、平文は 16 進数でエンコードされていることに注意してください。

import java.security.Provider;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

public class Cast6 {

    static final String KEY_ALGO = "CAST6";
    static final String CIPHER_ALGO = "CAST6/ECB/NOPADDING";
    
    static String keytext = "2342bb9efa38542c0af75647f29f615d";
    static String plaintext = "00000000000000000000000000000000";
    static String ciphertext = "c842a08972b43d20836c91d1b7530f6b";
    
    static Provider bc = new BouncyCastleProvider();
    
    public static void main(String[] args) throws Exception {
        
        System.out.println("encrypting");
        String actual = encrypt();
        System.out.println("actual: " + actual);
        System.out.println("expect: " + ciphertext);

        System.out.println("decrypting");
        actual = decrypt();
        System.out.println("actual: " + actual);
        System.out.println("expect: " + plaintext);
    }

    static String encrypt() throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGO, bc);
        
        byte[] keyBytes = Hex.decodeHex(keytext.toCharArray());
        SecretKeySpec key = new SecretKeySpec(keyBytes, KEY_ALGO);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        
        byte[] input = Hex.decodeHex(plaintext.toCharArray());
        byte[] output = cipher.doFinal(input);
        String actual = Hex.encodeHexString(output);
        return actual;
    }
    

    static String decrypt() throws Exception {
        Cipher cipher = Cipher.getInstance(CIPHER_ALGO, bc);
        
        byte[] keyBytes = Hex.decodeHex(keytext.toCharArray());
        SecretKeySpec key = new SecretKeySpec(keyBytes, KEY_ALGO);
        cipher.init(Cipher.DECRYPT_MODE, key);
        
        byte[] output = cipher.doFinal(Hex.decodeHex(ciphertext.toCharArray()));
        
        String actual = Hex.encodeHexString(output);
        return actual;  
    }

}
于 2013-07-31T16:04:22.683 に答える