选择正确的 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);
}
}
我的应用程序操纵数据库标识符。我希望对我的用户隐藏这些值。
我正在寻找一种方法,在这些标识符从服务器端传递到客户端时对其进行加密,并在它们以相反的方式传递时对其进行解密。
供您参考,未加密的标识符是整数(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);
}
}