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.

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

报告相同问题?

悬赏问题

  • ¥15 乌班图ip地址配置及远程SSH
  • ¥15 怎么让点阵屏显示静态爱心,用keiluVision5写出让点阵屏显示静态爱心的代码,越快越好
  • ¥15 PSPICE制作一个加法器
  • ¥15 javaweb项目无法正常跳转
  • ¥15 VMBox虚拟机无法访问
  • ¥15 skd显示找不到头文件
  • ¥15 机器视觉中图片中长度与真实长度的关系
  • ¥15 fastreport table 怎么只让每页的最下面和最顶部有横线
  • ¥15 java 的protected权限 ,问题在注释里
  • ¥15 这个是哪里有问题啊?