如何使用 Rijndael 和 256 位块大小进行加密或解密?

发布于 2024-12-15 02:35:55 字数 225 浏览 2 评论 0原文

由于某些原因,我需要使用 256 位块大小来实现 Rijndael 解/压缩,而不是使用 128 位块大小的 AES(原因:使用 Rijndael 在 PHP 中对数据进行加密...)。

如何更改密码的块大小?

如果我只是得到一个带有 "RIJNDAEL/CFB/PKCS5Padding" 的密码并尝试用 256 位初始化 IV,我会得到一个异常,因为块大小只有 128 位。

For certain reasons I need to implement Rijndael de/compression with a blocksize of 256 bits instead of AES which uses a block size of 128 bits (reason: data is encrypted in PHP using Rijndael...).

How can I change the block-size for a cipher?

If i just get a cipher with "RIJNDAEL/CFB/PKCS5Padding" and try to initialize a IV with 256 bits I get an exception, because the block-size is only 128 bits.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

哀由 2024-12-22 02:35:55

除了具有 128 位块大小的 Rijndael 之外,任何 Sun JCE 提供程序都不支持任何其他算法:这是 AES 算法。要获得 256 位块大小的 rijndael,您必须去其他地方。我建议使用 Bouncycastle java 库。 RijndaelEngine 类有一个构造函数接受以位为单位的块大小。大多数人都会找到 PlatedBufferedBlockCipher 类与合适的填充物一起使用时会更方便,例如

PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new RijndaelEngine(256), new PKCS7Padding());

There is no support in any of the Sun JCE providers for anything other than Rijndael with the 128-bit blocksize: this is the AES algorithm. To get rijndael with the 256-bit blocksize you will have to go somewhere else. I suggest the Bouncycastle java library. The RijndaelEngine class has a constructor that accepts a block size in bits. Most people find the PaddedBufferedBlockCipher class to be more convenient when used with suitable padding, e.g.

PaddedBufferedBlockCipher c = new PaddedBufferedBlockCipher(new RijndaelEngine(256), new PKCS7Padding());
喵星人汪星人 2024-12-22 02:35:55

请注意,PHP mcrypt 使用零字节填充,因此应使用 new ZeroBytePadding() 而不是 new PKCS7Padding()

下面是使用 CBC 和 RIJNDAEL 256 的完整实现。

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.RijndaelEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.ZeroBytePadding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Base64;

public static String encryptWithAesCBC(String plaintext, String key, String iv)
{
    try {
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());
        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes());
        cipher.init(true, ivAndKey);
        return new String(Base64.encode(cipherData(cipher, plaintext.getBytes())));
    } catch (InvalidCipherTextException e) {
        throw new RuntimeException(e);
    }
}

public static String decryptWithAesCBC(String encrypted, String key, String iv)
{
    try {
        byte[] ciphertext = Base64.decode(encrypted);
        PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());

        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes());
        aes.init(false, ivAndKey);
        return new String(cipherData(aes, ciphertext));
    } catch (InvalidCipherTextException e) {
        throw new RuntimeException(e);
    }
}

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data) throws InvalidCipherTextException
{
    int minSize = cipher.getOutputSize(data.length);
    byte[] outBuf = new byte[minSize];
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
    int length2 = cipher.doFinal(outBuf, length1);
    int actualLength = length1 + length2;
    byte[] cipherArray = new byte[actualLength];
    for (int x = 0; x < actualLength; x++) {
        cipherArray[x] = outBuf[x];
    }
    return cipherArray;
}

 private String md5(String string)
 {
    try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(string.getBytes());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
            sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    } catch (java.security.NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

使用 CFB 时,PlatedBufferedBlockCipher 应替换为以下内容:

PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CFBBlockCipher(new RijndaelEngine(256),8), new ZeroBytePadding());
// PHP mcrypt uses a blocksize of 8 bit for CFB

用法:

String salt = "fbhweui3497";
String key = md5(salt);
String iv = md5(md5(salt));

String encrypted = encryptWithAesCBC("text to encript", key, iv);

String decrypted = decryptWithAesCBC(encrypted, key, iv);

Note that PHP mcrypt uses Zero Byte padding so new ZeroBytePadding() should be used instead of new PKCS7Padding().

Bellow a full implementation using CBC and RIJNDAEL 256.

import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.RijndaelEngine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.paddings.ZeroBytePadding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Base64;

public static String encryptWithAesCBC(String plaintext, String key, String iv)
{
    try {
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());
        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes());
        cipher.init(true, ivAndKey);
        return new String(Base64.encode(cipherData(cipher, plaintext.getBytes())));
    } catch (InvalidCipherTextException e) {
        throw new RuntimeException(e);
    }
}

public static String decryptWithAesCBC(String encrypted, String key, String iv)
{
    try {
        byte[] ciphertext = Base64.decode(encrypted);
        PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RijndaelEngine(256)), new ZeroBytePadding());

        CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(key.getBytes()), iv.getBytes());
        aes.init(false, ivAndKey);
        return new String(cipherData(aes, ciphertext));
    } catch (InvalidCipherTextException e) {
        throw new RuntimeException(e);
    }
}

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data) throws InvalidCipherTextException
{
    int minSize = cipher.getOutputSize(data.length);
    byte[] outBuf = new byte[minSize];
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
    int length2 = cipher.doFinal(outBuf, length1);
    int actualLength = length1 + length2;
    byte[] cipherArray = new byte[actualLength];
    for (int x = 0; x < actualLength; x++) {
        cipherArray[x] = outBuf[x];
    }
    return cipherArray;
}

 private String md5(String string)
 {
    try {
        java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
        byte[] array = md.digest(string.getBytes());
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < array.length; ++i) {
            sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
        }
        return sb.toString();
    } catch (java.security.NoSuchAlgorithmException e) {
        throw new RuntimeException(e);
    }
}

When using CFB, PaddedBufferedBlockCipher should be replace by the following:

PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CFBBlockCipher(new RijndaelEngine(256),8), new ZeroBytePadding());
// PHP mcrypt uses a blocksize of 8 bit for CFB

Usage:

String salt = "fbhweui3497";
String key = md5(salt);
String iv = md5(md5(salt));

String encrypted = encryptWithAesCBC("text to encript", key, iv);

String decrypted = decryptWithAesCBC(encrypted, key, iv);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文