[Java en .NET] Wachtwoord encrypten en decrypten

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Hoi,

Ik ben een Android app aan het schrijven (in Java) waar gebruikers hun wachtwoord voor een bepaald forum moeten invoeren. Mijn app heeft dit wachtwoord nodig om in te loggen op het forum en daar data vanaf te halen.

Het inloggen op het forum en het data ophalen gebeurt echter allemaal in een webservice op mijn webserver (om verscheidene redenen). Om het een en ander veilig te houden bedacht ik dat het mogelijk zou moeten zijn om het wachtwoord in mijn app (Java), die encrypted string op te sturen naar mijn webservice, om hem daar weer te decrypten en het originele wachtwoord te gebruiken. Ik zou dan een symmetrisch algoritme gebruiken (bijvoorbeeld Rijndael en AES kom ik veel tegen), dat in de app en in de webservice dezelfde key gebruikt, die niemand anders mag weten.

Ten eerste: is dit veilig, of vergis ik me nu? Ik denk dat het verzenden van data van een android app (via HTTP POST) onderschept kan worden en het wachtwoord dus gezien zou kunnen worden, niet? Als het wachtwoord encrypted is kan niemand er natuurlijk wat mee, tenzij ze de key weten. En daar ligt nu net een punt waar ik vaak tegenaan loop: kun je een Android app niet gewoon decompilen en zo de key uitlezen? Hoe zit dat met elk ander encryptie algoritme, je moet toch ergens de key opslaan, en waarom kan men die dan niet zomaar uitlezen?


Ik heb voor nu maar even aangenomen dat dit een veilige manier is om met het wachtwoord om te gaan (zo niet, advies om dit te verbeteren is handig!). Maar nu krijg ik het niet voor elkaar om een string in Java te encrypten en in .NET weer te decrypten. Of ik krijg allemaal errors (aan een of beide kanten), of ik krijg na decrypten gewoon iets anders terug.

Ik weet niet heel veel van de theorie dus ik raak nogal gauw verstrengeld in de verschillende implementaties, modes, settings, etc, en die zullen natuurlijk allemaal gelijk moeten zijn aan beide kanten om het originele wachtwoord weer terug te krijgen...


In Java gebruik ik op dit moment deze code om een wachtwoord te encrypten (Key en IV zijn natuurlijk even gauw verzonnen);
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class PasswordEncryption
{
    private static final String KEY = "1234567890123456";
    private static final String IV =  "abcdefghijklmnop";
    
    public static String encryptPassword(String password) throws Exception
    {
        SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "AES");
        AlgorithmParameterSpec IVspec = new IvParameterSpec(IV.getBytes());
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        
        byte[] encryptedBytes = cipher.doFinal(password.getBytes());
        return Base64Coder.encode(encryptedBytes).toString();
    }   
}

Base64Coder is een class die ik op internet gevonden heb, ik neem maar even voor het gemak (bij gebrek aan beter weten) aan dat die de bytes correct naar een base-64 string converteert.


Als ik hier bijvoorbeeld het wachtwoord "test" mee encrypt krijg ik "[C@bb273cc" terug.

Nu probeer ik dit in C# weer te decrypten met deze code, en ontelbaar veel variaties daar op, maar het wil niet lukken:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    public static class PasswordEncryption
    {
        private const string KEY = "1234567890123456";
        private const string IV =  "abcdefghijklmnop";

        public static string Decrypt(string encryptedPassword)
        {
            using (var aes = new AesManaged())
            {
                aes.Padding = PaddingMode.PKCS7;
                aes.KeySize = 128; 
                aes.Key = System.Text.Encoding.UTF8.GetBytes(KEY);
                aes.IV = System.Text.Encoding.UTF8.GetBytes(IV);
                byte[] cipherText = System.Text.Encoding.UTF8.GetBytes(encryptedPassword);
                byte[] plainText = null;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                    {
                        cs.Write(cipherText, 0, cipherText.Length);
                    }

                    plainText = ms.ToArray();
                }
                string s = System.Text.Encoding.UTF8.GetString(plainText);
                return s;
            }
        }
    }


In dit geval geeft hij "Length of the data to decrypt is invalid." na de CryptoStream.Write call. Ik heb geprobeerd andere encoding te gebruiken (Encoding.Unicode bijv), wat ik soms tegen kom online, maar dan zeurt hij dat de IV niet de goeie lengte heeft. Ik heb geprobeerd RijndaelManaged te gebruiken, zelfde problemen. Ik heb geprobeerd aan de Java kant de string als Hex terug te geven, weer hetzelfde...

Ik ben bang dat ik hier niet verder mee ga komen omdat ik gewoon niet goed weet wat voor settings ik allemaal kan en moet wijzigen, welke encoding ik moet gebruiken, etc.

Kan iemand misschien een tip geven hoe ik dit het beste kan aanpakken? Ik kom online heel veel libraries tegen die allemaal encrypties kunnen toepassen, maar daar heb ik niet zoveel aan als ze niet dezelfde settings en algoritmes gebruiken natuurlijk. Zijn er misschien implementaties die voor Java en C# beide werken?

Bedankt!

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Ben ik nou gek, of vergeet je de Base64 decode aan de .Net kant? Verder vraag ik me af of je getBytes() aan beide kanten wel op dezelfde manier gebruikt. Aan de .Net kant gebruikt je expliciet UTF-8, aan de Java kant niet.

Overigens heeft het m.i. niet zo veel zin wat je doet. Als je gewoon via een secure channel (HTTPS) jouw webservice aanroept, is het wachtwoord al niet meer van de lijn af te plukken. In feite zit je nu je eigen secure channel te bouwen, als ik goed begrijp wat je wilt bereiken.

Sowieso mag je er niet vanuit gaan dat welk shared secret dan ook veilig is als onderdeel van de app (je moet dan, zoals hieronder aangegeven, kijken naar public-key oplossingen).

[ Voor 107% gewijzigd door Herko_ter_Horst op 06-02-2012 21:38 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • Tarilo
  • Registratie: December 2007
  • Laatst online: 10-09 19:49
Blijkbaar heb je niet helemaal door hoe encryptie werkt, aangezien je AES symmetrisch noemt. Echter is juist iets als AES uitermate geschikt voor dit soort werk, aangezien dit een asymmetrische encryptie vorm is. Dit betekent dat de sleutel voor het encrypten(in je app) en decrypten(op de server) verschillend zijn. Het mooie van dit systeem is dat het in een klap niet meer uitmaakt of iemand achter de sleutel in je app komt, deze sleutel kan namelijk alleen maar gebruikt worden om iets te encrypten en niet om een wachtwoord te decrypten.

Als ik jou was zou ik even wat googlen op asymmetrische encryptie en public-private keys.

edit: oops, dikke vergissing. Feit blijft dat met asymmetrische encryptie je natuurlijk precies het probleem van de TS oplost, namelijk hoe voorkom je dat de key aan client zijde bekend wordt.

[ Voor 13% gewijzigd door Tarilo op 06-02-2012 21:06 ]


Acties:
  • 0 Henk 'm!

  • glocom
  • Registratie: Februari 2010
  • Laatst online: 22-11-2022
Je zou kunnen kijken wat de waarde heeft van encryptedPassword aan de .Net kant.
Want je weet namelijk de exacte string die je vanaf Java verstuurd, en dan kun je controleren dat je dat ook volledig ontvangt.

Acties:
  • 0 Henk 'm!

  • Nvidiot
  • Registratie: Mei 2003
  • Laatst online: 03-06 16:38

Nvidiot

notepad!

7laurens7 schreef op maandag 06 februari 2012 @ 21:00:
Blijkbaar heb je niet helemaal door hoe encryptie werkt, aangezien je AES symmetrisch noemt. Echter is juist iets als AES uitermate geschikt voor dit soort werk, aangezien dit een asymmetrische encryptie vorm is.
[...]
Euh? Niet dus: "The algorithm described by AES is a symmetric-key algorithm, meaning the same key is used for both encrypting and decrypting the data." (Wikipedia: Advanced Encryption Standard)

What a caterpillar calls the end, the rest of the world calls a butterfly. (Lao-Tze)


Acties:
  • 0 Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 15:22
Misschien een "domme" opmerking, maar waarom dan niet gewoon HTTPS gebruiken?

Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Dat zei ik al :)

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • bwerg
  • Registratie: Januari 2009
  • Niet online

bwerg

Internettrol

Sowieso hashes van wachtwoorden gebruiken trouwens, het is gebruikelijk dat een server de wachtwoorden in plaintext niet kent (nouja, plaintext is wél gebruikelijk maar dat is niet zo netjes :P).

Heeft geen speciale krachten en is daar erg boos over.


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Ik lees nergens dat de TS de wachtwoorden ergens op wil slaan, dus hashes zijn een beetje voorbarig.

Hashes heeft de TS niets aan, aangezien zijn server de communicatie met het externe forum gaat opzetten. Daar heeft hij toch echt de plaintext passwords voor nodig.

[ Voor 46% gewijzigd door Herko_ter_Horst op 06-02-2012 21:44 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 15:22
Oops, over het hoofd gezien (heb de antwoorden ook maar gescimd, blijkbaar was dat er tussenuit gevallen). :+
bwerg schreef op maandag 06 februari 2012 @ 21:26:
Sowieso hashes van wachtwoorden gebruiken trouwens, het is gebruikelijk dat een server de wachtwoorden in plaintext niet kent (nouja, plaintext is wél gebruikelijk maar dat is niet zo netjes :P).
Daar gaat het niet over. Het probleem van de TS situeert zich in het veilig versturen van de gebruikersnaam en het wachtwoord van de client naar de server (voor verificatie). Hij wilt dus (basale) sniffing al zeker tegen gaan.

Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Herko_ter_Horst schreef op maandag 06 februari 2012 @ 20:55:
Ben ik nou gek, of vergeet je de Base64 decode aan de .Net kant? Verder vraag ik me af of je getBytes() aan beide kanten wel op dezelfde manier gebruikt. Aan de .Net kant gebruikt je expliciet UTF-8, aan de Java kant niet.
Dat kan best onderdeel van het probleem zijn ja, ik zal er morgen nog eens beter naar kijken. Ik heb het overigens ook met andere encodings geprobeerd maar krijg overal het probleem dat de lengte niet klopt.
Herko_ter_Horst schreef op maandag 06 februari 2012 @ 20:55:Overigens heeft het m.i. niet zo veel zin wat je doet. Als je gewoon via een secure channel (HTTPS) jouw webservice aanroept, is het wachtwoord al niet meer van de lijn af te plukken. In feite zit je nu je eigen secure channel te bouwen, als ik goed begrijp wat je wilt bereiken.

Sowieso mag je er niet vanuit gaan dat welk shared secret dan ook veilig is als onderdeel van de app (je moet dan, zoals hieronder aangegeven, kijken naar public-key oplossingen).
HTTPS heb ik nog niet aan gedacht, helemaal geen ervaring mee dus daar zal ik dan eens naar kijken. Als ik het via HTTPS verstuur kan ik het dus gewoon veilig als plain-text versturen (en het HTTPS gebeuren zorgt dan voor de encryptie?)
glocom schreef op maandag 06 februari 2012 @ 21:01:
Je zou kunnen kijken wat de waarde heeft van encryptedPassword aan de .Net kant.
Want je weet namelijk de exacte string die je vanaf Java verstuurd, en dan kun je controleren dat je dat ook volledig ontvangt.
Dat is het probleem in ieder geval niet, om te testen heb ik de hele android / communicatie zooi eruit gehaald, het is nu gewoon een los-staand Java programmaatje die m'n encrypted wachtwoord genereerd, en die copy/paste ik in een los-staand .NET programmaatje die het omgekeerde doet.
bwerg schreef op maandag 06 februari 2012 @ 21:26:
Sowieso hashes van wachtwoorden gebruiken trouwens, het is gebruikelijk dat een server de wachtwoorden in plaintext niet kent (nouja, plaintext is wél gebruikelijk maar dat is niet zo netjes :P).
Hashen is niet mogelijk want ik moet met het plaintext wachtwoord op het forum inloggen.
Overigens zal het forum achter de schermen vast wel alles hashen, maar ik moet inloggen door de username/password combinatie met HTTP POST naar de login pagina te sturen (en daarna de cookie opslaan en meesturen met volgende requests), dus het wachtwoord zal daarna pas gehashed worden.
7laurens7 schreef op maandag 06 februari 2012 @ 21:00:
edit: oops, dikke vergissing. Feit blijft dat met asymmetrische encryptie je natuurlijk precies het probleem van de TS oplost, namelijk hoe voorkom je dat de key aan client zijde bekend wordt.
Ik dacht dat het juist makkelijk zou zijn om een symmetrisch algoritme te gebruiken omdat er niemand anders iets hoeft te decrypten. Alleen m'n webservice doet decryptie en die kan ik veilig de key 'vertellen'. Maar je hebt wel een punt dat op een andere manier het niet meer uitmaakt als de key bekend word aan de app kant.


Bedankt voor de reacties, ik ga er morgen nog eens naar kijken. Vooral HTTPS klinkt goed, als ik dan niet zelf met encryptie aan de gang hoef, want dat is dus juist de stap die me niet lukt...

[ Voor 4% gewijzigd door NickThissen op 06-02-2012 22:52 ]

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Kun je niet veel beter kijken naar zaken als OAUTH ofzo? Of heb je geen invloed op dat forum?

[ Voor 45% gewijzigd door RobIII op 06-02-2012 23:51 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • bwerg
  • Registratie: Januari 2009
  • Niet online

bwerg

Internettrol

Herko_ter_Horst schreef op maandag 06 februari 2012 @ 21:29:
Hashes heeft de TS niets aan, aangezien zijn server de communicatie met het externe forum gaat opzetten. Daar heeft hij toch echt de plaintext passwords voor nodig.
Ah zo, ik lees te snel. Excusez-moi, negeert U mij vooral.

Heeft geen speciale krachten en is daar erg boos over.


Acties:
  • 0 Henk 'm!

  • Jegorex
  • Registratie: April 2004
  • Laatst online: 03-09 23:24
Java kun je gewoon decompilen en volgens mij zijn er ook wel programmas om Android apps te decompilen, maar daar heb ik verder nooit naar gekeken.
Je kunt wel een obfuscator zoals ProGuard gebruiken, dat maakt het begrijpen van je code moeilijker, maar het zal nog steeds mogelijk zijn om de key te weten te komen.

Zoals hierboven al genoemd is zal HTTPS het makkelijkst zijn denk ik.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Jegorex schreef op dinsdag 07 februari 2012 @ 01:00:
Java kun je gewoon decompilen en volgens mij zijn er ook wel programmas om Android apps te decompilen, maar daar heb ik verder nooit naar gekeken.
Je kunt wel een obfuscator zoals ProGuard gebruiken, dat maakt het begrijpen van je code moeilijker, maar het zal nog steeds mogelijk zijn om de key te weten te komen.
Allemaal Security through obscurity. Gebruik gewoon een Asymmetrische encryptie methode of ga voor iets als OAUTH oid.

Valt me overigens net pas op:
NickThissen schreef op maandag 06 februari 2012 @ 20:45:
Als ik hier bijvoorbeeld het wachtwoord "test" mee encrypt krijg ik "[C@bb273cc" terug.
Dan zou ik die base64coder class eens nakijken; base64 bevat enkel A-Z, a-z, 0-9, + en / met eventueel nog padding met het = teken. Dus [ en @ kunnen allebei niet eens voorkomen.

[ Voor 33% gewijzigd door RobIII op 07-02-2012 01:13 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 11-09 13:16
Het lijkt op een geheugenadres, minus 4 bits. :)

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 13:21

Haan

dotnetter

NickThissen schreef op maandag 06 februari 2012 @ 22:48:
HTTPS heb ik nog niet aan gedacht, helemaal geen ervaring mee dus daar zal ik dan eens naar kijken. Als ik het via HTTPS verstuur kan ik het dus gewoon veilig als plain-text versturen (en het HTTPS gebeuren zorgt dan voor de encryptie?)
Een wachtwoord wordt op enig moment altijd als plain-text verstuurd, je typt immers niet zelf een gehashte versie van je wachtwoord in als je ergens inlogt ;) Een goede website biedt daarom een inlogpagina aan via https.

Het zou dus geen probleem hoeven te zijn om het wachtwoord plain-text door te sturen naar je server. Je zal alleen wel een certificaat moeten kopen, maar dat zijn ook de kosten niet.

[ Voor 5% gewijzigd door Haan op 07-02-2012 08:25 ]

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Ik heb eens gekeken naar public key encryption (RSA), en hoewel het idee me wel duidelijk is ontgaan de praktische details me nog een beetje...

Klopt het dat ik op de server een key-pair moet genereren (een public key en een private key), en de public key daarna moet opsturen naar de Android app? De app kan dan met die public key (die iedereen mag zien) het wachtwoord encrypten, en op de server kan ik met de private key het bericht weer decrypten.

Als dit klopt zal er dus een extra communicatie nodig zijn. In plaats van dat de app gewoon de username en het encrypted wachtwoord opstuurt, zal de app nu eerst de key moeten opvragen. Dat is verder geen probleem, maar volgens mij zal het wel zo moeten werken, toch? Dat is net de stap die ik eigenlijk nergens duidelijk kan vinden, in alle voorbeelden encrypten ze wat data die ze daarna meteen weer decrypten, ja lekker handig, maar niet echt relevant als ik de data dus wil doorsturen naar iemand anders.

Ik ga weer even knutselen...

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 13:21

Haan

dotnetter

Je kan toch gewoon die key in je app coden? Zo werken heel veel API's (Facebook, LinkedIn, e.d.)

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
NickThissen schreef op maandag 06 februari 2012 @ 20:45:
Het inloggen op het forum en het data ophalen gebeurt echter allemaal in een webservice op mijn webserver (om verscheidene redenen). Om het een en ander veilig te houden bedacht ik dat het mogelijk zou moeten zijn om het wachtwoord in mijn app (Java), die encrypted string op te sturen naar mijn webservice, om hem daar weer te decrypten en het originele wachtwoord te gebruiken. Ik zou dan een symmetrisch algoritme gebruiken (bijvoorbeeld Rijndael en AES kom ik veel tegen), dat in de app en in de webservice dezelfde key gebruikt, die niemand anders mag weten.
Daarmee krijg je nog altijd de mogelijkheid tot een replay-attack. Gebruik SSL, dan kan je in principe het wachtwoord wel plaintext in je XML zetten (SSL zorgt dan voor de versleuteling). Kijk anders naar een key exchange protocol zoals SRP.
In Java gebruik ik op dit moment deze code om een wachtwoord te encrypten (Key en IV zijn natuurlijk even gauw verzonnen);
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class PasswordEncryption
{
    private static final String KEY = "1234567890123456";
    private static final String IV =  "abcdefghijklmnop";
    
    public static String encryptPassword(String password) throws Exception
    {
        SecretKeySpec key = new SecretKeySpec(KEY.getBytes(), "AES");
        AlgorithmParameterSpec IVspec = new IvParameterSpec(IV.getBytes());
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
        
        byte[] encryptedBytes = cipher.doFinal(password.getBytes());
        return Base64Coder.encode(encryptedBytes).toString();
    }   
}

Base64Coder is een class die ik op internet gevonden heb, ik neem maar even voor het gemak (bij gebrek aan beter weten) aan dat die de bytes correct naar een base-64 string converteert.

Als ik hier bijvoorbeeld het wachtwoord "test" mee encrypt krijg ik "[C@bb273cc" terug.
Ik zie twee problemen in je code:
1) Je roept op password getBytes() aan zonder het karakterset te specificeren. Als dezelfde code op een systeem met een andere locale wordt aangeroepen kan dit onverwachte problemen geven. Zorg er voor dat je altijd expliciet de encoding opgeeft als je een String naar een array van bytes omzet en ook andersom! Gezien je .NET code zou je denk ik .getBytes("UTF-8") moeten gebruiken
2) Ik ken Base64Coder niet, maar ik gok op basis van de resultaat string dat Base64Coder.encode(...) niet een String teruggeeft, maar een char array. Een aanroep van toString() op een array levert een representatie op inclusief een deel van de hashcode. De "[C" betekent: 'array van char'.
Als je een string wilt hebben zul je het volgende moeten doen:
Java:
1
return new String(Base64Coder.encode(encryptedBytes));
Nu probeer ik dit in C# weer te decrypten met deze code, en ontelbaar veel variaties daar op, maar het wil niet lukken:
Fix eerst de problemen die ik hierboven beschreven heb in Java, grote kans dat het daarna gewoon werkt.

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Remus schreef op dinsdag 07 februari 2012 @ 13:34:
1) Je roept op password getBytes() aan zonder het karakterset te specificeren. Als dezelfde code op een systeem met een andere locale wordt aangeroepen kan dit onverwachte problemen geven. Zorg er voor dat je altijd expliciet de encoding opgeeft als je een String naar een array van bytes omzet en ook andersom! Gezien je .NET code zou je denk ik .getBytes("UTF-8") moeten gebruiken
Ik denk eerder iets als Encoding.UTF8.GetBytes(somestring);

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
RobIII schreef op dinsdag 07 februari 2012 @ 14:57:
[...]

Ik denk eerder iets als Encoding.UTF8.GetBytes(somestring);
Ik heb het over wat hij in zijn Java code moet gebaseerd op wat hij al in zijn C# code doet. Bovenstaande constructie bestaat niet in Java.

Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Bedankt voor de suggesties, ik ben weer iets verder.


Ik heb nu in C# een key-pair gegenereerd, wat me per key (public en private) een modulus en exponent geeft in base64 gecodeerd. De private key is opgeslagen op de server, de public key gebruik ik rechtstreeks in Java om een PublicKey object te genereren:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class PasswordEncryption
{
    private static final String PublicKeyModulus = "z7biRfbX45mTaGOZxgFL+3kPkWhUqIzpwrBXkx19YHQH6ypTosevK1hkrloLnCF4BdGnEV/OK2ZEc+040yUtWj9sP2FJWHGCAFmAt8LgRrH/vjUBUHDZQ3iorTEJQQoL6D/IqJMN5FsJkKlZPZPfhGhR7nh0Hbxy7XXlK3Y5Gus=";
    private static final String PublicKeyExponent = "AQAB";
    
    public static String encryptPassword(String password) throws Exception
    {
        // Decode base64 key strings
        byte[] m = Base64Coder.decode(PublicKeyModulus);
        byte[] e = Base64Coder.decode(PublicKeyExponent);
        
        // Decode password into bytes
        byte[] plainText = password.getBytes("UTF-8");
                        
        // Create public key from modulus + exponent
        BigInteger modulus = new BigInteger(1, m);  
        BigInteger exponent = new BigInteger(1, e);     
        RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(modulus, exponent);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");         
        PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); 

        // Create cipher 
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        
        // Encrypt password bytes
        byte[] encryptedBytes = cipher.doFinal(plainText);
        
        // Return base64 encoded string
        String encrypted = new String(Base64Coder.encode(encryptedBytes));
        return encrypted;
    }   
}

Ik gebruik ten eerste Base64Coder om de modulus en exponent van de public key naar bytes om te zetten, en daarna maak ik er een PublicKey van (voorbeeldje gevonden op internet, lijkt te werken).

Het wachtwoord zet ik om in bytes via UTF-8 encoding, en die bytes encrypt ik daarna met de public key. De bytes die ik terug krijg zet ik weer om naar base64 en die toon ik tijdelijk in een textboxje. Je had gelijk dat Base64Coder een char array terug geeft, niet goed gekeken, nu geeft hij iets terug wat op base64 lijkt.

Als ik hiermee het wachtwoord "test" encrypt krijg ik deze string terug:
code:
1
reBh4IAxaGjjWDrRMbdrjatKlJNd6s4PkXxD3y8RU0EMoqXjZtTkfzsXrQj36doC1EvWg+bFbUw5XFOJlJpYfEgOB03R1YSmsicbfp6h9t4w0cl8p2r2YSsKXngj12AwFsdSMvujINmvn222/cROXEluyQgm9wKsgRFW5At036Q=


Het vreemde vind ik echter dat ik elke keer dat ik deze code draai een ander resultaat krijg. Dat vind ik niet logisch, alles is toch statisch, de key blijft hetzelfde en het wachtwoord ook, hoe kan er dan een ander encrypted string uitkomen?

Ik zit nog even te kijken of ik dit weer terug kan decrypten in C# maar dat lukt nog even niet..

[ Voor 14% gewijzigd door NickThissen op 07-02-2012 15:28 ]

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Ok, het is gelukt! Met behulp van een EncryptionLibrary die ik laatst gevonden heb, heb ik het bericht weer kunnen decrypten met de private key. Blijkbaar is het normaal dat het encrypted bericht elke keer anders is, want elk bericht decrypt gewoon netjes naar de juiste string :)

Bedankt voor de hulp...

Hier is de C# code die ik gebruik. Ik kan helaas de library zelf niet meer zo gauw vinden, als iemand hem nodig heeft dan zoek ik nog wel even of dan stuur ik hem wel door...
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
using System;
using System.Text;
using EncryptionClassLibrary.Encryption;

namespace iRacingForumService
{
    public class PasswordEncryption
    {
        private PasswordEncryption()
        {
            _Rsa = new Asymmetric(1024);
            _PrivateKey = new Asymmetric.PrivateKey();
            _PrivateKey.LoadFromXml(System.IO.File.ReadAllText("private.key"));
        }

        private static PasswordEncryption _Instance;
        public static PasswordEncryption Instance
        {
            get { return _Instance ?? (_Instance = new PasswordEncryption()); }
        }

        private readonly Asymmetric _Rsa;
        public Asymmetric Rsa { get { return _Rsa; } }

        private readonly Asymmetric.PrivateKey _PrivateKey;
        private Asymmetric.PrivateKey PrivateKey { get { return _PrivateKey; } }

        private readonly Encoding _Encoding;
        private Encoding Encoding { get { return _Encoding; } }

        public string Decrypt(string encryptedPassword)
        {
            var encryptedBytes = Convert.FromBase64String(encryptedPassword);
            var encryptedData = new Data(encryptedBytes);

            var decryptedData = this.Rsa.Decrypt(encryptedData, this.PrivateKey);
            return Encoding.UTF8.GetString(decryptedData.Bytes);
        }
    }
}


Ik sla de private key nu in een XML file op, op m'n webserver. Ik denk dat dit geen probleem is, of wel?

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
En nu snap ik er weer niks van...

Als ik een string encrypt in mijn Java test programmaatje, en die daarna laat decrypten door m'n webserver, dan werkt het prima. Als ik met dezelfde code een string encrypt in m'n Android app, dan kan m'n webserver hem niet decoden.

Ik krijg nu voor "test" als encryptie (in base64):
code:
1
LTVEUyUgt2nFEVGQ5wX4JMv3gcA6iqttpbrgoNeapWHFNZ2J3TpsghYVKowwcamzLv8VzBqkeVfFTda7WXQCNK9ZsouMJE9cjcce9aVUd3aoi0zqwfWaiMUSnmjSg5TcIGcHdPTQuG4lMR9PPXylpKRpwx5K/tDlVIClyiU72js=

Nu krijg ik "Bad Data" te zien bij het decrypten aan de C# kant. Verder geen informatie in de exception, enkel "Bad Data"...

Genereer ik een encrypted string via m'n test programmaatje dan werkt het wel prima. Het is exact dezelfde code.

Kan het iets met de encoding te maken hebben die misschien anders is in Windows en in de Java emulator (= Linux?)?

[ Voor 3% gewijzigd door NickThissen op 07-02-2012 16:39 ]

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
Ik begrijp dat je nu verder wilt met uitzoeken hoe encryptie werkt? Je probleem kun je namelijk een stuk eenvoudiger oplossen met HTTPS...

[ Voor 20% gewijzigd door Herko_ter_Horst op 07-02-2012 18:03 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Herko_ter_Horst schreef op dinsdag 07 februari 2012 @ 18:02:
Ik begrijp dat je nu verder wilt met uitzoeken hoe encryptie werkt? Je probleem kun je namelijk een stuk eenvoudiger oplossen met HTTPS...
Tsja, ik wilde eerst het encryptie verhaal even verder uitzoeken, en toen ik alle suggesties hier probeerde kreeg ik het al gauw aan de praat. Echter alleen in een testje, vanuit de Android emulator werkt het niet, maar ik hoop dat dat een eenvoudige verklaring heeft... Zo niet kan ik nog altijd naar HTTPS gaan kijken.

Probleem wordt dan ook dat ik vanuit Android de webservice anders moet gaan benaderen neem ik aan? Ik heb het nu net eindelijk lekker draaien, daar heeft ook al wat trial en error in gezeten, dus ik wilde het eerst proberen op de manier waarop ik niet met die server communicatie hoef te klooien.

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Herko_ter_Horst
  • Registratie: November 2002
  • Niet online
NickThissen schreef op dinsdag 07 februari 2012 @ 18:41:
[...]

Tsja, ik wilde eerst het encryptie verhaal even verder uitzoeken, en toen ik alle suggesties hier probeerde kreeg ik het al gauw aan de praat. Echter alleen in een testje, vanuit de Android emulator werkt het niet, maar ik hoop dat dat een eenvoudige verklaring heeft... Zo niet kan ik nog altijd naar HTTPS gaan kijken.

Probleem wordt dan ook dat ik vanuit Android de webservice anders moet gaan benaderen neem ik aan? Ik heb het nu net eindelijk lekker draaien, daar heeft ook al wat trial en error in gezeten, dus ik wilde het eerst proberen op de manier waarop ik niet met die server communicatie hoef te klooien.
Nee hoor, als je je webservice eerst via http://mijnserver.nl/webservice benaderde, gaat dat dan via https://mijnserver.nl/webservice. Je moet deze dan aanroepen via een HttpsURLConnection (aangenomen dat je nu een HttpURLConnection gebruikt, anders moet je even in het framework dat je gebruikt de betreffende class of parameter opzoeken/zetten). Aan je webservice verandert verder niets.

Voorwaarde is wel, dat je server een certificaat gebruikt dat vertrouwd is door de client. Dat betekent in de meeste gevallen een certificaat gesigned door een partij die al bekend is in de lijst van vertrouwde partijen in je browser/op je device. Als je het met een self-sign certificate wilt doen, zul je wat meer moeite moeten doen.

[ Voor 24% gewijzigd door Herko_ter_Horst op 07-02-2012 19:00 ]

"Any sufficiently advanced technology is indistinguishable from magic."


Acties:
  • 0 Henk 'm!

  • Thralas
  • Registratie: December 2002
  • Laatst online: 14:11
Herko_ter_Horst schreef op dinsdag 07 februari 2012 @ 18:02:
Ik begrijp dat je nu verder wilt met uitzoeken hoe encryptie werkt? Je probleem kun je namelijk een stuk eenvoudiger oplossen met HTTPS...
En als bonus kun je de server authenticeren en ben je af van een major drawback van je huidige implementatie (niet replay attack-safe).

Betreffende je interoperabilityprobleem, waarschijnlijk heeft het iets te maken met de opmerking die hier staat, of er is een verschil in padding (PKCS#1 v1.5 vs. OAEP?).

In 't algemeen: begin niet aan crypto. Als het toch moet, dan veilig (helaas
ontbreekt een C#-implementatie vooralsnog).

Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Herko_ter_Horst schreef op dinsdag 07 februari 2012 @ 18:54:
[...]

Nee hoor, als je je webservice eerst via http://mijnserver.nl/webservice benaderde, gaat dat dan via https://mijnserver.nl/webservice. Je moet deze dan aanroepen via een HttpsURLConnection (aangenomen dat je nu een HttpURLConnection gebruikt, anders moet je even in het framework dat je gebruikt de betreffende class of parameter opzoeken/zetten). Aan je webservice verandert verder niets.

Voorwaarde is wel, dat je server een certificaat gebruikt dat vertrouwd is door de client. Dat betekent in de meeste gevallen een certificaat gesigned door een partij die al bekend is in de lijst van vertrouwde partijen in je browser/op je device. Als je het met een self-sign certificate wilt doen, zul je wat meer moeite moeten doen.
Ik zal er eens naar kijken. Ik weet verder niks van HTTPS, ik zou niet eens weten hoe ik mijn webservice pagina als https kan benaderen, hoe stel je dat in? Ik neem aan dat dit via de server moet gebeuren, normaal zou je dat via IIS doen ofzo (geen ervaring mee, ik doe alles via een online control panel van m'n webhost, en daar kan ik niks over https vinden).
Thralas schreef op woensdag 08 februari 2012 @ 01:21:
[...]


En als bonus kun je de server authenticeren en ben je af van een major drawback van je huidige implementatie (niet replay attack-safe).

Betreffende je interoperabilityprobleem, waarschijnlijk heeft het iets te maken met de opmerking die hier staat, of er is een verschil in padding (PKCS#1 v1.5 vs. OAEP?).

In 't algemeen: begin niet aan crypto. Als het toch moet, dan veilig (helaas
ontbreekt een C#-implementatie vooralsnog).
Ik heb het nu net aan de praat gekregen. Het probleem had iets te maken met de verschillende opties en padding methodes inderdaad, het blijkt dat java in windows en op android verschillende defaults gebruikt, dus nu specificeer ik alles handmatig en werkt het wel gewoon goed.

Ik zal ook eens naar keyczar kijken, klinkt wel interessant, maar als er geen C# implementatie is dan moet ik dus weer opnieuw met trial en error gaan zitten kijken hoe ik het weer kan decrypten, niet zoveel zin in nu ik net alles aan de praat heb eerlijk gezegd...

Eerlijk gezegd is de security helemaal niet zo relevant, het gaat om een forum reader, het boeit totaal niet of iemand anders met jou login het forum kan lezen. Het enige waar het me om gaat is dat je wachtwoord niet gestolen kan worden door iemand anders, omdat ze dan op de main site (niet alleen het forum) ook kunnen inloggen en dat is een stuk vervelender. Zolang het wachtwoord dus encrypted is kan niemand ooit achter het wachtwoord van iemand anders komen neem ik aan? Ik sla de plain text wachtwoorden ook nergens op (hoogstens de encrypte wachtwoorden in de android app).

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • SaphuA
  • Registratie: September 2005
  • Laatst online: 10-09 22:00
.

[ Voor 116% gewijzigd door SaphuA op 31-01-2022 15:39 ]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
OMG stop hiermee. Zoals je nu andermans wachtwoorden wilt opslaan is per definitie een slecht plan, en er is per definitie een plek waar je het wachtwoord kan lekken.

De enige juiste oplossing een protocol a la OAuth, of iets dmw sessions waardoor je niet zelf het wachtwoord hoeft te onthouden.

Iedereen die meehelpt met de originele vraag van harte bedankt: Je helpt mee aan een verkeerde oplossing en een security probleem. Zelfs al bevat het forum in kwestie geen gevoelige data, wachtwoorden blijven dat nog altijd wel. Als iemand een hetzelfde wachtwoord op meerdere plekken gebruikt, wat uiteraard af te raden is, ben jij uiteindelijk toch medeverantwoordelijk.

[/rant]

TL:DR: Wat een (*&$^@$^6 plan. Ik zou niet eens de topictitel durven typen. :X

[ Voor 3% gewijzigd door Voutloos op 08-02-2012 12:01 ]

{signature}


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
SaphuA schreef op woensdag 08 februari 2012 @ 11:50:
Als je er voor kiest om zelf de wachtwoorden te encrypten, gebruik dan aub geen symmetrische encyptie. Het is niet zo moeilijk om de key te achterhalen uit de applicatie. Daarna is het slechts een kwestie van een bericht onderscheppen en je hebt een wachtwoord. Tuurlijk, de kans is klein dat iemand zoveel moeite gaat doen, maar je creeert zo een schijnveiligheid en dat is niet eerlijk tegenover je gebruikers.

Het is vele malen veiliger om gebruik te maken van asymmetrische encryptie. Als iemand dan de client key heeft, heeft hij niets aan het onderscheppen van een bericht. Als je de server key lang genoeg maakt en er zeker van bent dan niemand daar bij kan is je applicatie, zonder veel extra moeite, al een stuk veiliger.

(Je kunt nog een stukje verder te gaan door per request een nieuwe key pair te genereren. Hierdoor hoef je je ook geen zorgen te maken dat iemand de server key kan achterhalen.)
Ik gebruik asymmetrische encryptie. Per request een nieuwe key genereren had ik ook al aan gedacht en dat zou ik zonder veel moeite moeten kunnen implementeren.
Voutloos schreef op woensdag 08 februari 2012 @ 12:00:
OMG stop hiermee. Zoals je nu andermans wachtwoorden wilt opslaan is per definitie een slecht plan, en er is per definitie een plek waar je het wachtwoord kan lekken.

De enige juiste oplossing een protocol a la OAuth, of iets dmw sessions waardoor je niet zelf het wachtwoord hoeft te onthouden.

Iedereen die meehelpt met de originele vraag van harte bedankt: Je helpt mee aan een verkeerde oplossing en een security probleem. Zelfs al bevat het forum in kwestie geen gevoelige data, wachtwoorden blijven dat nog altijd wel. Als iemand een hetzelfde wachtwoord op meerdere plekken gebruikt, wat uiteraard af te raden is, ben jij uiteindelijk toch medeverantwoordelijk.
Ik sla nergens het plain-text wachtwoord op. Het enige wat ik opsla, als de gebruiker dat wil, is de encryptie van het wachtwoord, zodat een gebruiker niet keer op keer zijn wachtwoord in hoeft te typen. Dit sla ik op in de android app. Ik zie niet in hoe dit anders is dan, bijvoorbeeld, een browser die een username/wachtwoord combinatie onthoudt, of hoe het uberhaupt anders is dan een wachtwoord in een willekeurige website / applicatie in voeren. Om in te loggen zal de gebruiker toch ooit zijn wachtwoord moeten geven, daar kan ik niet omheen... OAuth klinkt leuk maar is geen optie want ik heb geen controle over het forum, ik heb gewoon de username en het wachtwoord nodig, anders lukt het per definitie niet.

Als de gebruiker zijn wachtwoord niet wil invullen kan hij de app niet gebruiken, zo simpel is het gewoon.

Aangezien ik alleen de encrypted versie op sla is er verder toch ook geen gevaar dat het echte wachtwoord bekend zou worden? De enige optie die ik zie (corrigeer me aub als dat niet klopt) is dat iemand toegang krijgt tot m'n webserver en de private key kan zien. Een oplossing daarvoor zou zijn om elke keer een nieuwe key te genereren, maar in dat geval kan ik het wachtwoord ook niet meer opslaan, of ik zou het in plaintext moeten opslaan wat toch een veel groter gevaar met zich meebrengt (telefoon gejat bijv)..

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Dus je gebruikt 's werelds enige forum welke zonder sessies werkt? Of mist dat enkel in hun xmlrpc/soap/json/whatever API?

{signature}


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
De enige manier om op het moment (geautomatiseerd) informatie uit het forum te halen is door middel van een HTTP GET naar de login pagina te doen met username en wachtwoord. Daar krijg ik een cookie uit terug die ik in elke volgende request (met HTTP POST) meestuur zodat "ik" toegang heb tot de pagina. Er is geen API, ik moet gewoon de HTML van de pagina's downloaden en parsen. Het lijkt erop dat het een handgeschreven forum is, het is in ieder geval geen standaard vBulletin of whatever.

Dat is ook een van de redenen waarom ik het graag via een webservice doe. Als ik alles vanuit de Android app ga doen dan moet ik dus het wachtwoord als plain-text met HTTP GET naar de login pagina sturen, en dat is volgens mij geen goed idee... Nu doet mijn webservice dat, en het lijkt me dat dit een stuk veiliger is.

[ Voor 7% gewijzigd door NickThissen op 08-02-2012 13:02 ]

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Als je nou gewoon die sessie (cookie data) onthoudt ipv het wachtwoord was je in 5 minuten klaar geweest en had je nog een betere oplossing ook. KISS.

O en om de inkopper voor te zijn: Eens in de zoveel maanden je wachtwoord opnieuw moeten invullen (mochten sessies verloren gaan) weegt niet zwaarder dan de redenen om geen wachtwoorden op te slaan.

Je huidige plan is alleen leuk als je van negatieve publiciteit houdt en bij het eerste de beste lek de frontpage halen wilt.

[ Voor 15% gewijzigd door Voutloos op 08-02-2012 13:07 ]

{signature}


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Voutloos schreef op woensdag 08 februari 2012 @ 13:04:
Als je nou gewoon die sessie (cookie data) onthoudt ipv het wachtwoord was je in 5 minuten klaar geweest en had je nog een betere oplossing ook. KISS.

O en om de inkopper voor te zijn: Eens in de zoveel maanden je wachtwoord opnieuw moeten invullen (mochten sessies verloren gaan) weegt niet zwaarder dan de redenen om geen wachtwoorden op te slaan.

Je huidige plan is alleen leuk als je van negatieve publiciteit houdt en bij het eerste de beste lek de frontpage halen wilt.
Het is me nog steeds niet duidelijk wat ik daar mee kan bereiken.

Ik zal toch ooit een keer een wachtwoord moeten krijgen en naar de login pagina moeten sturen om uberhaupt die cookie data te krijgen. En als ik die data heb dan kan ik die op de server opslaan maar niet terugsturen naar de app, toch? Dan zou het weer onderschept kunnen worden...

Maar hoe laat ik een gebruiker dan authenticeren? Ik zou alleen de username kunnen meesturen van app naar webservice, en aan de hand van de username de bijbehorende cookie data op de server opzoeken, maar dan zou dus iedereen (nadat iemand 1 keer heeft ingelogd) zich kunnen voordoen als die gebruiker door gewoon zijn username te gebruiken... Dat lijkt me ook niet echt de bedoeling.

Verder weet ik toevallig dat de cookie data erg snel verloopt, dus "eens in de zoveel maanden" wordt dan eerder "eens in de zoveel uur".

Het is leuk om de hele tijd cynische berichtjes te plaatsen over wat ik allemaal wel niet fout doe, maar ik zou het wel op prijs stellen als je even in detail wil uitleggen hoe ik het dan beter kan doen. Dat is de reden dat ik dit topic maak, en als je alleen maar verteld dat het fout is en niet hoe het beter kan dan help je zelf natuurlijk ook niet echt mee... No offence verder, je hebt er duidelijk meer verstand van dan ik, maar zo kom ik er ook niet uit.

[ Voor 13% gewijzigd door NickThissen op 08-02-2012 13:48 ]

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 15:22
Voutloos schreef op woensdag 08 februari 2012 @ 12:00:
OMG stop hiermee. [...]
Iedereen die meehelpt met de originele vraag van harte bedankt: Je helpt mee aan een verkeerde oplossing en een security probleem.
[/rant]
Mocht je het topic überhaupt volledig gelezen hebben, zou je sommige van die uitspraken toch wel een stuk anders mogen formuleren. Overigens lees je het ook verkeerd.

1. Het gaat hier om het versturen van username + password van client naar de server om "in te loggen".
2. Je mag mij eens uitleggen waar de security lek zit in het versturen van deze data over HTTPS?
Voutloos schreef op woensdag 08 februari 2012 @ 13:04:
O en om de inkopper voor te zijn: Eens in de zoveel maanden je wachtwoord opnieuw moeten invullen (mochten sessies verloren gaan) weegt niet zwaarder dan de redenen om geen wachtwoorden op te slaan.

Je huidige plan is alleen leuk als je van negatieve publiciteit houdt en bij het eerste de beste lek de frontpage halen wilt.
Met het verkeerde been uit bed gestapt ofzo? |:( Overigens heeft de TS geen controle over het systeem waartegen hij probeert te spreken.
Voutloos schreef op woensdag 08 februari 2012 @ 13:04:
Als je nou gewoon die sessie (cookie data) onthoudt ipv het wachtwoord was je in 5 minuten klaar geweest en had je nog een betere oplossing ook. KISS.
Dat is inderdaad een mogelijkheid, maar dan nog moet hij af en toe om username/password vragen indien de sessie verlopen is. Uiteraard moet je wel de session id bijhouden voor de huidige sessie, kwestie van niet voor elke request te moeten inloggen. Maar daarbij is het probleem nog steeds niet opgelost dat hij de username/password combinatie op een veilige manier wilt versturen. En dan zijn we terug bij het begin, de eerste reply, gemaakt door Herko_ter_Horst, het gebruik van HTTPS.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
HTTPS is alleen een oplossing voor de onderlinge communicatie, en heeft 0.0 invloed op security in de rest van de schakels. Neemt niet weg dat je, zeker op mobiele apparaten, standaard https zou moeten willen gebruiken.

Na doorvragen blijkt dus dat er een mogelijkheid tot het gebruiken van sessies was, dus dat is al een heel stuk minder gevoelig.

De opnieuw om wachtwoord aanvragen inkopper had ik al direct erbij gezet.


Ik ben niet met het verkeerde been uit bed gestapt, ik verbaas/erger me gewoon in grote mate dat er anno nu nog steeds mensen zijn die liever wachtwoorden van derden opslaan als er ook alternatieven zijn. Ik probeer mezelf nog zelfs een beetje genuanceerd uit te drukken, want anders had ik het wel bij enkel 'dit is een slecht plan en er lijkt een alternatief te zijn: lees je in of zoek aub een andere hobby' gelaten. :>

Maar negeer gerust dit goed bedoelde advies: zolang je niet bij mij komt werken of ik je app niet hoef te gebruiken slaap ik er zeker niet minder van hoor.

[ Voor 13% gewijzigd door Voutloos op 08-02-2012 14:18 ]

{signature}


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
Voutloos schreef op woensdag 08 februari 2012 @ 14:15:
Ik ben niet met het verkeerde been uit bed gestapt, ik verbaas/erger me gewoon in grote mate dat er anno nu nog steeds mensen zijn die liever wachtwoorden van derden opslaan als er ook alternatieven zijn. Ik probeer mezelf nog zelfs een beetje genuanceerd uit te drukken, want anders had ik het wel bij enkel 'dit is een slecht plan en er lijkt een alternatief te zijn: lees je in of zoek aub een andere hobby' gelaten. :>
Er (b)lijkt in dit geval helemaal geen realistisch alternatief te zijn. Ik vind dat je toon eerlijkgezegd nogal agressief en verder geeft je reactie weinig blijk dat je het topic ook aandachtig gelezen hebt.

Als je moet inloggen op het systeem van derden en als er geen persistent session mogelijk is op dat systeem dan heb je geen andere keuze dan het wachtwoord op een of andere manier op te slaan. Tenzij je de gebruiker iedere keer weer om het wachtwoord wil vragen; wat je door de gebruiker ook niet in dank afgenomen zal worden. En dan zal je linksom of rechtsom toch enige vorm van encryptie moeten gebruiken bij zowel het opslaan als het versturen.

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Goed er staat pas in de laatste reactie dat de sessie maar een paar uur gelden is, dus dan houdt het inderdaad op.

Excuses voor het ongemak dat ik als enige doorvraag of er niet een betere oplossing is. Ik zal me voortaan als er direct zonder morren en verdere toelichting voor de slechte oplossing gegaan wordt afzijdig houden, zodat we er zeker van zijn dat er niets geleerd wordt.


edit:
OK, je hebt wel gelijk over mijn toon. Maar ik meende het wel. :P

[ Voor 62% gewijzigd door Voutloos op 08-02-2012 15:26 ]

{signature}


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Ik begrijp Voutloos' reactie wel, maar ook TS' oplossing valt goed te praten, zoals Remus inderdaad uitlegt.

Als het hier om specifieke forumsoftware gaat, die geen ondersteuning voor OpenAuth heeft, geen API heeft, en waar verder eigenlijk alleen maar via plain old HTTP POST is in te loggen en de sessie middels een tijdelijk cookie is te onthouden, dan is het te verdedigen om de credentials op te slaan.

Als het forum dan ook nog eens geen HTTPS-login aanbiedt, kan het ook nog te verdedigen zijn om de credentials op jouw server (mits die uiteraard wél enkel via HTTPS te bereiken is!) te bewaren. Zo kunnen de gegevens in ieder geval nooit uit de app lekken (open Wifi, foute proxy, bug in local storage, vul maar in).

Zolang je ervan uitgaat dat de verbinding tussen jouw service en het uiteindelijke forum niet gekaapt kan worden èn je ervoor zorgt dat jouw database niet leeggetrokken kan worden, begeef je je volgens mij nog niet echt op glad ijs.

@edit: :D

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Remus
  • Registratie: Juli 2000
  • Laatst online: 15-08-2021
Voutloos schreef op woensdag 08 februari 2012 @ 14:36:
Goed er staat pas in de laatste reactie dat de sessie maar een paar uur gelden is, dus dan houdt het inderdaad op.

Excuses voor het ongemak dat ik als enige doorvraag of er niet een betere oplossing is. Ik zal me voortaan als er direct zonder morren en verdere toelichting voor de slechte oplossing gegaan wordt afzijdig houden, zodat we er zeker van zijn dat er niets geleerd wordt.
Doe maar lekker verongelijkt omdat iemand je aanspreekt op je manier van communiceren... Punt is dat je gewoon BAM het topic inramt dat de TS en alle eerdere reacties stom bezig zijn etc etc en dat het gewoon allemaal fout is. Dat is een stijl van communiceren die bij mij enige wrevel oproept (al zal ik dat zelf vast ook regelmatig doen), belangrijker nog: het zorgt ervoor dat mensen de intentie van je bericht niet meer lezen, maar alleen het 'JE DOET HET VERKEERD!11!!one'.

In plaats van je post (empasis mine):
OMG stop hiermee. Zoals je nu andermans wachtwoorden wilt opslaan is per definitie een slecht plan, en er is per definitie een plek waar je het wachtwoord kan lekken.

De enige juiste oplossing een protocol a la OAuth, of iets dmw sessions waardoor je niet zelf het wachtwoord hoeft te onthouden.

Iedereen die meehelpt met de originele vraag van harte bedankt: Je helpt mee aan een verkeerde oplossing en een security probleem. Zelfs al bevat het forum in kwestie geen gevoelige data, wachtwoorden blijven dat nog altijd wel. Als iemand een hetzelfde wachtwoord op meerdere plekken gebruikt, wat uiteraard af te raden is, ben jij uiteindelijk toch medeverantwoordelijk.
etcetc had je ook kunnen vragen of die site niet zoiets als OAuth of andere persistent sessions ondersteunt, en of hij al goed had nagedacht over de veiligheidsconsequenties van zijn huidige oplossing.

Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Goed, zullen we weer terug on topic gaan? Het is vast en zeker allemaal goed bedoeld maar op deze manier werkt het natuurlijk ook niet ;)


Een paar punten die ik tegen kwam:
CodeCaster schreef op woensdag 08 februari 2012 @ 14:41:

Als het forum dan ook nog eens geen HTTPS-login aanbiedt, kan het ook nog te verdedigen zijn om de credentials op jouw server (mits die uiteraard wél enkel via HTTPS te bereiken is!) te bewaren. Zo kunnen de gegevens in ieder geval nooit uit de app lekken (open Wifi, foute proxy, bug in local storage, vul maar in).
Ik zie net dat het forum wel een HTTPS login pagina aanbiedt (maar die gebruik ik momenteel geloof ik niet). Maar omdat ik via mijn webservice wil inloggen (en niet direct via mijn app), zal ik toch eerst het wachtwoord van app naar webservice moeten krijgen, en daarvoor zal ik dus encryptie moeten gebruiken (zelf of HTTPS gebruiken), dus dat is niet heel relevant.
Ik zou natuurlijk het inloggen rechtstreeks vanuit m'n app kunnen doen (als dat via HTTPS kan en wel veilig is), maar dan weet mijn webservice niet dat een gebruiker ingelogd is en zal ik dus op een of andere manier die cookie data moeten gaan doorsturen, en dan zit ik toch met hetzelfde probleem... Begrijp ik dit stuk in ieder geval goed?

De beste oplossing schijnt dus HTTPS te zijn. Ik heb even nagevraagd en helaas ondersteunt mijn webhost dat niet direct, maar moet ik daarvoor bij betalen. De prijs voor de SSL optie is echter in verhouding met de prijs voor de host zelf erg duur. Ik ga eerst even kijken of er toevallig betere hosts zijn waar SSL misschien al inbegrepen zit, of waar ik voor een vergelijkbare prijs wat meer features krijg...
Als ik HTTPS wil gebruiken zal ik dus eerst m'n webservice via HTTPS moeten kunnen aanbieden, en daarna hoef ik enkel (in de Android app Java code) te zorgen dat ik een HttpsConnection of iets dergelijks gebruik, en kan ik de parameters daarna (via JSON) gewoon als plain-text meegeven (in ieder geval niet zelf gaan encrypten, dat zou SSL dan voor me doen)? Dat moet verder wel goedkomen dan denk ik...

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Als jouw service ook (zelfstandig) data van dat forum moet halen, lijkt het mij het handigst om al het ophalen van data en inloggen in die service te doen, en niet ook nog eens in de app.

Verder is HTTPS zoals gezegd niet zaligmakend, maar wel om de transportlaag (in verband met wifi, proxy) te beveiligen.

[ Voor 7% gewijzigd door CodeCaster op 08-02-2012 15:28 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Ok, als ik nu wil voorkomen dat de gebruiker elke keer opnieuw zijn wachtwoord moet invullen, hoe werkt dat dan als ik https gebruik? In dat geval zal ik het wachtwoord plain-text moeten opslaan op het android device; als ik zelf encryptie toepas kan ik het alvast encrypten en dan pas opslaan, dat lijkt me dan een stuk veiliger toch? De enige andere optie (naast het wachtwoord zelf opslaan) is dus om de sessie details (= cookie data?) op te slaan? Dan zou m'n webservice dus na het inloggen die details terug moeten sturen (dat zou via HTTPS veilig zijn), maar als zo'n sessie maar eventjes geldig is werkt dat natuurlijk ook niet.

Wat me nog niet duidelijk is is waarom het zo'n probleem is als ik zelf encryptie toepas. Het is misschien wat lastiger te implementeren (maar momenteel beschik ik niet over https dus dat is al meteen lastiger) maar als het goed werkt komt het dan niet op hetzelfde neer? Of gaat het puur om het gevaar dat de private key uit zou lekken?

Verder: er zijn toch zoveel apps en browsers die je wachtwoord gewoon op kunnen slaan, waarom is dat daar geen probleem?

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • NickThissen
  • Registratie: November 2007
  • Laatst online: 09-09 10:50
Kleine bump, ik kom er nog steeds niet uit...

Volgens mij zijn dit nu de problemen:

1. Ik moet het plaintext wachtwoord van app naar webservice sturen. Ik zie twee mogelijkheden om dit enigszins veilig te doen: zelf het wachtwoord encrypten, of een HTTPS verbinding gebruiken.

2. Ik wil ook de login van een gebruiker in de app onthouden zodat deze niet elke keer opnieuw ingevoerd hoeft te worden. Volgens mij is er geen andere mogelijkheid dan gewoon de username en het wachtwoord op te slaan. Als ik zelf encryptie toepas kan ik echter het encrypted wachtwoord opslaan, wat me een stuk veiliger lijkt (ik heb in de app nooit het plaintext wachtwoord nodig, enkel in de webservice). Als ik HTTPS gebruik kan dit niet en zal ik dus het plaintext wachtwoord op moeten slaan, geen goed idee?

Ik weet dus niet welke keuze ik moet maken, eigen encryptie heeft als voordeel dat het wachtwoord encrypted opgeslagen kan worden, en als nadeel dat het waarschijnlijk minder veilig is. Om te voorkomen dat de private key uitlekt zou ik elke keer een nieuwe key kunnen genereren, maar dan is m'n voordeel (opslaan van encrypted password) weg.
Als ik HTTPS gebruik kan ik ook niet het encrypted wachtwoord opslaan.

Is er nog een optie die ik over het hoofd zie?

Mijn iRacing profiel


Acties:
  • 0 Henk 'm!

  • Styxxy
  • Registratie: Augustus 2009
  • Laatst online: 15:22
Heb je geen encrypted application store waar je gegevens in kan wegschrijven? Hiermee bedoel ik dus een storage unit waar je data in kan wegschrijven, zonder dat andere applicaties eraan kunnen.

Een andere mogelijkheid is om die combinatie op te slaan op jouw webservice, en dan aan de hand van een unieke id die gegevens terug vinden (adv sessio-id & device-id & ...).

EDIT: voor Android, kijk eens hier (internal storage). Dat lijkt me exact hetgeen je nodig hebt voor het tweede probleem.

[ Voor 22% gewijzigd door Styxxy op 10-02-2012 10:46 ]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
NickThissen schreef op vrijdag 10 februari 2012 @ 09:53:
Als ik HTTPS gebruik kan dit niet en zal ik dus het plaintext wachtwoord op moeten slaan, geen goed idee?
Dit heeft geen invloed op elkaar. Dat bij https die communicatie encrypted plaats vindt is wat betreft jouw apps transparant; het verandert verder helemaal niets, heeft 0.0 invloed op de data die je kan versturen.

{signature}


Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 21-08 17:09
NickThissen schreef op vrijdag 10 februari 2012 @ 09:53:
Kleine bump, ik kom er nog steeds niet uit...

Volgens mij zijn dit nu de problemen:

1. Ik moet het plaintext wachtwoord van app naar webservice sturen. Ik zie twee mogelijkheden om dit enigszins veilig te doen: zelf het wachtwoord encrypten, of een HTTPS verbinding gebruiken.

2. Ik wil ook de login van een gebruiker in de app onthouden zodat deze niet elke keer opnieuw ingevoerd hoeft te worden. Volgens mij is er geen andere mogelijkheid dan gewoon de username en het wachtwoord op te slaan. Als ik zelf encryptie toepas kan ik echter het encrypted wachtwoord opslaan, wat me een stuk veiliger lijkt (ik heb in de app nooit het plaintext wachtwoord nodig, enkel in de webservice). Als ik HTTPS gebruik kan dit niet en zal ik dus het plaintext wachtwoord op moeten slaan, geen goed idee?
Je kunt dan beter asymmetrische encryptie kunnen gebruiken. Je android app kan het alleen encrypten (die heeft de decriptie-sleutel niet), je webservice kan het alleen decrypten. Je hoeft dan in je webservice niet centraal de usernames/passwords van al die users op te slaan, die staan alleen op hun eigen app.

https://niels.nu

Pagina: 1