Results 1 to 4 of 4

Thread: MS SQL Server veld encryptie

  1. #1

    MS SQL Server veld encryptie

    Hallo forumleden,

    Ik ben bezig met het versleutelen van velden in een tabel voor MS SQL Server. Als voorbeeld heb ik een achternaam. De eigenschap van het veld is tekst (NVARCHAR), de maximale lengte van het veld is op dit moment 50 karakters. Nu dient het veld versleuteld te worden op basis van Rijndael. De lengte van een versleutelde data zal mogelijk meer dan de maximale 50 karakters zijn. Helaas is mij niet duidelijk wat de lengte van versleutelde data nu precies zal zijn. Wat moet ik nu doen. Dien ik de maximale veldgrootte aan te passen naar bijvoorbeeld 100 karakters 'NVARCHAR(100)' of dien ik de eigenschap aan te passen naar het maximum 'NVARCHAR(MAX)'? Bij MS SQL Server is 'MAX' gelijk aan 4000 karakters (8.000 bytes).

    Alvast bedankt voor jullie advies.
    Onmogelijk... Is geen feit, maar een mening.

  2. #2
    Rijndael is een block cypher, en voor zover ik begrepen heb, is de lengte van de versleutelde waarde dan een veelvoud van de block size van het algoritme. Voor Rijndael is dat 128 bits ofwel 16 bytes. M.a.w, een string van 50 tekens/bytes *) zal versleuteld dus maximaal 64 bytes worden (50 omhoog afgerond naar een veelvoud van 16). De key size die je gebruikt bij de versleuteling is daar ook een veelvoud van, maar speelt geen rol voor de benodigde ruimte.

    Die bytes moet je dan wel opslaan in een een binair veld, of omzetten naar een waarde die geldig is in een tekst veld, bijvoorbeeld naar een hex-string (aantal tekens = bytes*2), or base64 (aantal tekens = Ceil(bytes * 4/3)).

    Overigens maakt de maximale lengte van je velddefinitie niet zo heel veel uit voor de efficiency van je database. Een varchar wordt opgeslagen als een lengte-indicator plus een buffer met tekens. Die lengte-indicator is 1 of 2 bytes, afhankelijk van de maximale lengte.
    Als je de waarde 'X' opslaat, dan zal een varchar(260) zal dus maar 1 byte meer gebruiken dan een varchar(1), en net zoveel als een varchar(4000). In dit geval zou je voldoende moeten hebben aan 67 tekens voor een Base64 encoding van een encryptie van 50 tekens *). Maar bij twijfel kan je dus makkelijk gaan voor groter zonder dat het je heel veel kost.
    Een exacte lengte moet je dus meer zien als een functioneel constraint dan als een technische optimalisatie.

    *) Ik ga uit van tekens van 1 byte. Als je achternaam multi-byte tekens kan bevatten (een unicode veld is), dan kan dat aantal natuurlijk ook hoger zijn. Je moet dus eigenlijk niet uitgaan van het aantal tekens (50), maar van het maximale aantal bytes dat die tekens in zouden kunnen nemen in de encoding die de string heeft op het moment van encrypten. Als je het encrypten in Delphi doet, moet je daar dus ook rekening mee houden. Zelfs als je database ansi is, zal een string in Delphi standaard een unicode string zijn, en twee bytes per teken beslaan.
    Last edited by GolezTrol; 06-Jan-20 at 13:14.
    1+1=b

  3. #3
    Wauwza! Wat een mooi en uitgebreid antwoord. Dank je wel! Dat de maximale lengte geen technische optimalisatie is, dat wist ik niet eens. Dit betekent dat ik alle velden op MAX kan zetten zonder mij ik zorgen te hoeven maken over een enorme database? Of begrijp ik je dan verkeerd?
    Onmogelijk... Is geen feit, maar een mening.

  4. #4
    Tja, in langere velden kan je ook daadwerkelijk langere waarden opslaan, en dan neemt het natuurlijk wel meer ruimte in.

    Plus dat alle onderdelen van je software daar rekening mee moeten houden. Het zetten van een specifieke lengte heeft wat dat betreft een belangrijke functionele waarde, en het draagt ook uit wat de bedoeling is (bijvoorbeeld dat een achternaam geen 1000 tekens moet zijn).
    Maar inderdaad, daarvan afgezien maakt het niets uit.
    Kleine kanttekening dat mijn ervaring vooral met Oracle is, niet met MS SQL, maar volgens mij verschillend de databases in dit opzicht niet zoveel.

    In Oracle kan ik dit doen. Iets soortgelijks moet in SQL Server ook wel kunnen:

    SQL Code:
    1. CREATE TABLE PERSON1(LASTNAME varchar2(10));
    2. CREATE TABLE PERSON2(LASTNAME varchar2(250));
    3. CREATE TABLE PERSON3(LASTNAME varchar2(4000));
    4.  
    5. -- "Achternamen" '1' tot '1000000' invullen in elk van de tabellen
    6. INSERT INTO PERSON1 (LASTNAME) SELECT level FROM dual connect BY level <= 1000000;
    7. INSERT INTO PERSON2 (LASTNAME) SELECT level FROM dual connect BY level <= 1000000;
    8. INSERT INTO PERSON3 (LASTNAME) SELECT level FROM dual connect BY level <= 1000000;
    9. commit;
    10.  
    11. -- Kijken hoeveel ruimte dat nou eigenlijk inneemt
    12. SELECT segment_name, segment_type, bytes
    13. FROM dba_segments
    14. WHERE
    15.   segment_type='TABLE' AND
    16.   segment_name IN ('PERSON1', 'PERSON2', 'PERSON3');
    Die laatste query haalt de ruimte van de tabellen op. Die zijn voor alledrie hetzelfde, tw 14.680.064 bytes. De totale lengte van de lastnames is 5.888.896. De rest zal algemene overhead per rij zijn, dus een row header, en de lengte-headers van de varchars zelf. Als er daadwerkelijk 4000 bytes gereserveerd zou worden, zou PERSON3 veel meer ruimte in moeten nemen.
    1+1=b

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •