选择正确的 Jasypt 加密器实现以通过 HTTP 传递加密数据

Choosing the right Jasypt encryptor implementation for passing encrypted data via HTTP

我的应用程序操纵数据库标识符。我希望对我的用户隐藏这些值。

我正在寻找一种方法,在这些标识符从服务器端传递到客户端时对其进行加密,并在它们以相反的方式传递时对其进行解密。

供您参考,未加密的标识符是整数(java 长整数)。我还有一个进一步的要求,即 通过 HTTP 传递加密标识符。此外,加密值不一定是整数。

我目前使用带密码的 Jasypt StandardPBEBigIntegerEncryptor,但我得到:

org.jasypt.exceptions.EncryptionOperationNotPossibleException

任何人都可以根据我的要求从众多 Jasypt 类 中向我推荐 xxEncryptor 的适当实现吗?

edit: 我实际上只是想把一个 positive java long 加密成另一个 positive java长。数据恰好是一个 JPA 实体 ID:

private Long id;

然后我使用 Json 序列化程序 (JsonSerializer<Long>) 来加密从 REST 端点发送到 java 脚本客户端的数据和 Json反序列化器 (JsonDeserializer<Long>) 以解密 java 脚本客户端发送到 REST 端点的数据。

首先,确保您使用的是实际的 BigIntegers,而不是 Java 长整数。

myEncryptor.encrypt(new BigInteger(myId));

如果您在使用 BigIntegers 时仍然遇到问题,或者由于实体配置困难等原因无法直接使用它们,您可以将您的 ID 转换为字符串并使用 StandardPBEStringEncryptor 进行加密。

最后,检查以确保如果您在 HTTP 请求中传递这些,则不会将它们放入 GET 请求的查询字符串中。 Jasypt 将对内容进行 base64 编码,其中包括一些在 URL 中不起作用的字符,例如“=”。返回时,他们需要进入 POST,或进入 headers。

旁注:根据您的威胁模型,您可能希望使用设置密码以外的其他内容进行加密。也许使用 session 密钥作为密码。否则用户可能 不知道 实际密钥,但仍然能够复制加密值并在您不希望的其他上下文中重复使用它们。

public class Test {

    static Random r = new Random();

    static class Data {
        long id = r.nextLong();

        @Override
        public String toString() {
            return "Data{" + "id=" + id + '}';
        }
    }

    public static void main(String[] args) {
        List<Data> data = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            data.add(new Data());
        }

        final String password = "don't you ever tell them";

        byte[] passwordBytes = password.getBytes();
        long[] passwordLongs = new long[passwordBytes.length / 8];

        for (int i = 0; i < passwordLongs.length; i++) {
            ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
            byte[] chunk = new byte[Long.BYTES];
            System.arraycopy(passwordBytes, i*Long.BYTES, chunk, 0, Long.BYTES);
            buffer.put(chunk);
            buffer.flip();//need flip
            passwordLongs[i] = buffer.getLong();
        }

        System.out.println(data);

        ListIterator<Data> encryptIterator = data.listIterator();
        while (encryptIterator.hasNext()) {
            Data next = encryptIterator.next();
            next.id = next.id ^ passwordLongs[(encryptIterator.nextIndex()-1) % passwordLongs.length];
        }

        System.out.println(data);

        ListIterator<Data> decryptIterator = data.listIterator();
        while (decryptIterator.hasNext()) {
            Data next = decryptIterator.next();
            next.id = next.id ^ passwordLongs[(decryptIterator.nextIndex()-1) % passwordLongs.length];
        }

        System.out.println(data);
    }
}