2016-04-07 13 views
3

Ich verwende Spring Boot 1.3.3 zum Erstellen einer Webanwendung. Ich benutze Redis für die Behandlung der Sitzung.Redis, SpringBoot und HttpSession: sollte ich die Sitzungsdaten verschlüsseln?

Ich werde einige "entscheidende" Daten in die HttpSession setzen und ich würde gerne verstehen, wie dies mit Redis funktioniert. Sind die Informationen serverseitig und ein Schlüssel auf der Browserseite oder sind alle Daten in einem Cookie im Benutzerbrowser?

Ich möchte eine Dokumentation Referenz für die Antwort oder eine autoritative Antwort erhalten (z. B. ein Pivotal-Entwickler).

+0

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. –

Antwort

1

Sehr guter Artikel auf Redis Sicherheit vom Schöpfer oder redis - http://antirez.com/news/96 ist es ziemlich interessant zu lesen. Lesen Sie auch die Kommentare.

Eine Sache, die ich bin neugierig ist, müssen Ihre "entscheidenden" Daten in Sitzung gespeichert werden? Wenn es nicht sehr wichtig für die Leistung ist, können Sie es einfach in Ihrer Datenbank speichern. Ich benutze redis in unserem Produkt nur für die Speicherung von Tokens zusammen mit grundlegenden Benutzerdaten, ich habe Leute gesehen, die große Datenmenge als Sitzungsdaten ausgeben, was in Ordnung ist, aber ich denke nicht, dass es eine wirklich gute Idee ist.

+0

Ich möchte "klassische" Dinge wie Token, Einkaufswagen, Dinge für nicht registrierte Benutzer speichern. –

1

Meiner Meinung nach sollten Sie vermeiden, Daten in redis zu verschlüsseln, sonst wird es ein Leistungsoverhead sein. Daher sollten Sie Redis-Knoten in eine geschützte Zone (intern) einfügen, in die nur der Datenverkehr aus Ihrer Anwendung gelangen darf. Wenn dies nicht möglich ist, kann IPSec/Stunnel zur Sicherung der Kommunikation verwendet werden.

Übrigens ist das Speichern der Sitzungsdaten als HTTPSession-Attribut schneller als das Abrufen von es von Redis. Aber ich glaube, dass Sie wahrscheinlich wegen der Menge der Daten wieder gewählt hätten.

2

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:

  1. ich den obigen Code nicht getestet
  2. 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.
  3. Offensichtlich können Sie den gewünschten 2-Wege-Verschlüsselungsalgorithmus verwenden. EncrpytionUtils ist nur ein Beispiel.
  4. 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.
  5. 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.
  6. 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:

  1. SpringSession
  2. RedisOperationsSessionRepository
  3. SessionRepository