Während ich mit dem Großteil dessen, was die anderen Antworten hier gesagt haben, einverstanden bin, beantwortete keine der anderen Antworten die Frage. Ich gehe davon aus, dass Sie SpringSession mit Redis im Spring Boot verwenden.
Um SpringSession verwenden zu können, haben Sie wahrscheinlich (direkt oder indirekt) einen Servlet-Filter konfiguriert, der SessionRepositoryFilter
erweitert.
SessionRepositoryFilter verwendet eine SessionRepository
. Da Sie Redis verwenden, ist es wahrscheinlich, dass Ihre Konfiguration RedisOperationsSessionRepository
verwendet.
Implementiert SessionRepository
, wie Sie vielleicht erraten haben und letztlich für das Abrufen, Speichern und Löschen von Sitzungen basierend auf einem Schlüssel verantwortlich ist (in Ihrem Fall ein Schlüssel, der wahrscheinlich als Cookie im Browser des Benutzers gespeichert wird).
RedisOperationSessionRepository
, verwendet standardmäßig JdkSerializationRedisSerializer
, das RedisSerializer
implementiert, um Sitzungsdaten zu serialisieren, bevor diese Daten an Redis übergeben werden.
Gemäß der Dokumentation für RedisOperationSessionRepository
ist es möglich, den Standard-Serializer zu setzen, den RedisOperationSessionRepository
verwenden wird, über seine setDefaultSerializer
Methode.
Sie könnten theoretisch JdkSerializationRedisSerializer
erweitern und dort Verschlüsselung und Entschlüsselung durchführen.JdkSerializationRedisSerializer
sieht wie folgt aus:
public class JdkSerializationRedisSerializer implements RedisSerializer<Object> {
private Converter<Object, byte[]> serializer = new SerializingConverter();
private Converter<byte[], Object> deserializer = new DeserializingConverter();
public Object deserialize(byte[] bytes) {
if (SerializationUtils.isEmpty(bytes)) {
return null;
}
try {
return deserializer.convert(bytes);
} catch (Exception ex) {
throw new SerializationException("Cannot deserialize", ex);
}
}
public byte[] serialize(Object object) {
if (object == null) {
return SerializationUtils.EMPTY_ARRAY;
}
try {
return serializer.convert(object);
} catch (Exception ex) {
throw new SerializationException("Cannot serialize", ex);
}
}
}
So eine mögliche Art und Weise Verschlüsselung hinzuzufügen, könnte wie folgt aussehen:
public class CrypticRedisSerializer extends JdkSerializationRedisSerializer {
@Override
public Object deserialize(byte[] bytes) {
byte[] decrpyted;
try {
decrpyted = EncryptionUtils.decrypt(bytes);
return super.deserialize(decrpyted);
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// handle expections or allow to propagate, your choice!
return null;
}
@Override
public byte[] serialize(Object object) {
byte[] bytes = super.serialize(object);
try {
return EncryptionUtils.encrypt(bytes);
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// handle expections or allow to propagate, your choice!
return null;
}
}
Wo EncrpytionUtils aussehen könnte:
public class EncryptionUtils {
private static SecretKeySpec skeySpec;
static {
try {
ClassPathResource res = new ClassPathResource("key.key");
if(res != null){
File file = res.getFile();
FileInputStream input = new FileInputStream(file);
byte[] in = new byte[(int)file.length()];
input.read(in);
skeySpec = new SecretKeySpec(in, "AES");
input.close();
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
public static byte[] encrypt(byte[] input)
throws GeneralSecurityException, NoSuchPaddingException{
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
return cipher.doFinal(input);
}
public static byte[] decrypt(byte[] input) throws GeneralSecurityException, NoSuchPaddingException{
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
return cipher.doFinal(input);
}
}
Alles, was Sie tun, müssten Implementieren Sie dies, stellen Sie sicher, dass Sie Ihren benutzerdefinierten Serializer als Standard RedisOperationSessionRepository
Benutzer festlegen.
Bitte beachten Sie:
- ich den obigen Code nicht getestet
- ich befürworten bin nicht, dass der obige Code eine ideale Lösung oder die Lösung, sondern einfach einen Mechanismus demonstriert für encrpytion in SpringSession Einführung mit Redis.
- Offensichtlich können Sie den gewünschten 2-Wege-Verschlüsselungsalgorithmus verwenden. EncrpytionUtils ist nur ein Beispiel.
- Dies wirkt sich auf die Leistung aus. Wie viel? Schwer zu sagen ohne zu testen. Seien Sie sich jedoch bewusst, dass es Auswirkungen auf die Leistung haben wird.
- Wenn Sie wirklich besorgt sind über die Verschlüsselung von Sitzungsdaten, die an Redis gesendet werden, dann empfehle ich dringend, dass Sie auch sicherstellen, dass Ihre Server gesichert sind. Stellen Sie sicher, dass nur die Server, die auf Ihren Redis-Server zugreifen müssen, können. Platziere es hinter einer Firewall. Wenn Sie einen Cloud-Dienst wie AWS verwenden, platzieren Sie Ihren Redis-Server in einem VPN und in einem privaten Subnetz.
- Redis does not support connection encryption currently. Wie Sie jedoch vorschlagen, können Sie Sniped verwenden, um sicherzustellen, dass Ihre Verbindungen verschlüsselt sind.
Dokumentation und Referenz überprüfen:
- SpringSession
RedisOperationsSessionRepository
SessionRepository
Sind Sie mit SpringSession (http://docs.spring.io/spring- Sitzung/Dokumente/aktuelle/Referenz/HTML5/# Einführung) mit Redis? Wenn ja, kann ich diese Frage beantworten. Gib mir Bescheid. –