dongzhun4898 2014-10-25 12:33
浏览 155
已采纳

JAVA是php的MCRYPT_RIJNDAEL_256的可靠等价物

I need to access some data that used PHP encryption. The PHP encryption is like this.

base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($cipher), $text, MCRYPT_MODE_ECB));

As value of $text they pass the time() function value which will be different each time that the method is called in. I have implemented this in Java. Like this,

public static String md5(String string) {
    byte[] hash;

    try {
        hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
    } catch (NoSuchAlgorithmException e) {
        throw new RuntimeException("Huh, MD5 should be supported?", e);
    } catch (UnsupportedEncodingException e) {
        throw new RuntimeException("Huh, UTF-8 should be supported?", e);
    }

    StringBuilder hex = new StringBuilder(hash.length * 2);

    for (byte b : hash) {
        int i = (b & 0xFF);
        if (i < 0x10) hex.append('0');
        hex.append(Integer.toHexString(i));
    }

    return hex.toString();
}

public static byte[] rijndael_256(String text, byte[] givenKey) throws DataLengthException, IllegalStateException, InvalidCipherTextException, IOException{
    final int keysize;

    if (givenKey.length <= 192 / Byte.SIZE) {
        keysize = 192;
    } else {
        keysize = 256;
    }

    byte[] keyData = new byte[keysize / Byte.SIZE];
    System.arraycopy(givenKey, 0, keyData, 0, Math.min(givenKey.length, keyData.length));
    KeyParameter key = new KeyParameter(keyData);
    BlockCipher rijndael = new RijndaelEngine(256);
    ZeroBytePadding c = new ZeroBytePadding();
    PaddedBufferedBlockCipher pbbc = new PaddedBufferedBlockCipher(rijndael, c);
    pbbc.init(true, key);

    byte[] plaintext = text.getBytes(Charset.forName("UTF8"));
    byte[] ciphertext = new byte[pbbc.getOutputSize(plaintext.length)];
    int offset = 0;
    offset += pbbc.processBytes(plaintext, 0, plaintext.length, ciphertext, offset);
    offset += pbbc.doFinal(ciphertext, offset);
    return ciphertext;
}


public static String encrypt(String text, String secretKey) throws Exception {


    byte[] givenKey = String.valueOf(md5(secretKey)).getBytes(Charset.forName("ASCII"));

    byte[] encrypted = rijndael_256(text,givenKey);

    return new String(Base64.encodeBase64(encrypted));
}

I have referred this answer when creating MCRYPT_RIJNDAEL_256 method." Encryption in Android equivalent to php's MCRYPT_RIJNDAEL_256 "I have used apache codec for Base64.Here's how I call the encryption function,

long time= System.currentTimeMillis()/1000;
String encryptedTime = EncryptionUtils.encrypt(String.valueOf(time), secretkey);

The problem is sometimes the output is not similar to PHP but sometimes it works fine. I think that my MCRYPT_RIJNDAEL_256 method is unreliable. I want to know where I went wrong and find a reliable method so that I can always get similar encrypted string as to PHP.

  • 写回答

1条回答 默认 最新

  • douzhouqin6223 2014-10-25 14:11
    关注

    The problem is likely to be the ZeroBytePadding. The one of Bouncy always adds/removes at least one byte with value zero (a la PKCS5Padding, 1 to 16 bytes of padding) but the one of PHP only pads until the first block boundary is encountered (0 to 15 bytes of padding). I've discussed this with David of the legion of Bouncy Castle, but the PHP zero byte padding is an extremely ill fit for the way Bouncy does padding, so currently you'll have to do this yourself, and use the cipher without padding.

    Of course, as a real solution, rewrite the PHP part to use AES (MCRYPT_RIJNDAEL_128), CBC mode encryption, HMAC authentication, a real Password Based Key Derivation Function (PBKDF, e.g. PBKDF2 or bcrypt) and PKCS#7 compatible padding instead of this insecure, incompatible code. Alternatively, go for OpenSSL compatibility or a known secure container format.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效