2012-04-23 19 views
5

Sto tentando di implementare un codificatore di stringhe semplice per offuscare alcune parti di una stringa di URL (per impedire che vengano eliminate da un utente). Sto utilizzando il codice quasi identico al campione nel JCA guide, ad eccezione di:Evitare interruzioni di riga nella stringa di URL codificata e codificata

  • con DES (ammesso che sia un po 'più veloce di AES, e richiede una chiave più piccola) e
  • Base64 it/decodifica la stringa assicurati che rimanga sicuro per un URL.

Per motivi che non riesco a capire, la stringa di output termina con interruzioni di riga, che presumo non funzionerà. Non riesco a capire cosa sta causando questo. Suggerimenti su qualcosa di simile che sia più facile o indicazioni su altre risorse da leggere? Sto trovando tutti i riferimenti di crittografia un po 'sopra la mia testa (e eccessivo), ma una semplice implementazione ROT13 non funzionerà dato che voglio trattare con un set di caratteri più grande (e non voglio perdere tempo ad implementare qualcosa che probabilmente avere problemi con personaggi oscuri a cui non avevo pensato).

ingresso del campione (senza linea di rottura):

http://maps.google.com/maps?q=kansas&hl=en&sll=42.358431,-71.059773&sspn=0.415552,0.718918&hnear=Kansas&t=m&z=7 

Output di esempio (interruzioni di linea come illustrato di seguito):

GstikIiULcJSGEU2NWNTpyucSWUFENptYk4m5lD8RJl8l1CuspiuXiE9a07fUEAGM/tC7h0Vzus+ 
jAH6cT4Wtz2RUlBdGf8WtQxVDKZVOzKwi84eQh2kZT9T3KomlnPOu2owJ/2RAEvG+QuGem5UGw== 

mia codificare frammento:

final Key key = new SecretKeySpec(seed.getBytes(), "DES"); 
final Cipher c = Cipher.getInstance("DES"); 
c.init(Cipher.ENCRYPT_MODE, key); 
final byte[] encVal = c.doFinal(s.getBytes()); 
return new BASE64Encoder().encode(encVal); 
+1

hai provato a ripristinare la tua operazione di codifica e vedere se Funziona ? – Snicolas

+0

da dove proviene la classe BASE64Encoder? – leonbloy

+1

@leonbloy Stavo importando sun.misc.BASE64Decoder, che ho trovato grazie a [questo post] (http://stackoverflow.com/questions/2267036/work-sun-misc-base64encoder-decoder-for-getting- byte) non è una buona idea. – milletron

risposta

7

Base64 Encoder solito imporre una lunghezza massima (pezzo) e aggiungere nuove righe quando ne sario. Normalmente è possibile configurarlo, ma ciò dipende dalla particolare implementazione del codificatore. Ad esempio, la classe da Apache Commons ha un attributo linelength, impostandolo su zero (o negativo) disabilita la separazione della linea.

BTW: Sono d'accordo con l'altra risposta in quanto DES è difficilmente consigliabile oggi. Inoltre, stai solo "offuscando" o veramente crittografando? Chi ha la chiave? L'intera cosa non ha un buon odore per me.

+0

È davvero più offuscante della crittografia. Basta usare una stringa hardcoded come "chiave" nella classe chiamante (che è condivisa dai servlet che generano e consumano gli URL offuscati). Grazie per il lead di lunghezza lineare, indicato anche da @Jerry Coffin – milletron

+0

Poiché l'encoder Apache Commons afferma "... è codificato per codificare/decodificare solo codifiche di caratteri compatibili con il grafico ASCII inferiore 127", ha vinto " lavoro da quando avrò personaggi al di fuori di questo intervallo. Avendo bisogno di ripensare a tutto questo approccio, penso. – milletron

+0

"questo non funzionerà in quanto avrei caratteri al di fuori di questo intervallo": leggi attentamente: funziona con caratteri al di fuori di ASCII, è solo che la codifica binaria non può essere utf-16, ma può essere utf-8, o iso-8859-1, ecc. – leonbloy

1

Anche se è correlato alla tua domanda attuale, DES è generalmente più lento di AES (almeno nel software), quindi a meno che realmente bisogno di tenere la piccola chiave, AES è quasi certamente una scelta migliore.

In secondo luogo, è perfettamente normale che la crittografia (DES o AES) generi/produrrà caratteri di nuova riga nel suo output. Produrre l'output senza di essi sarà interamente basato sull'encoder di base 64, quindi è qui che devi chiaramente guardare.

Non è particolarmente sorprendente vedere una base 64 che inserisce caratteri di nuova riga a intervalli regolari nel suo output. L'uso più comune della codifica base-64 consiste nel mettere i dati grezzi in qualcosa di simile al corpo di un'e-mail, in cui una linea molto lunga potrebbe causare un problema. Per evitare ciò, i dati vengono suddivisi in pezzi, in genere non più di 80 colonne (e in genere un po 'meno). In questo caso, le nuove righe dovrebbero essere ignorate, tuttavia, quindi dovresti essere in grado di eliminarle, se la memoria è disponibile.

11

È sufficiente eseguire base64Str = base64Str.replaceAll("(?:\\r\\n|\\n\\r|\\n|\\r)", "") sulla stringa codificata.

Funziona correttamente quando si prova a decodificarlo in byte. L'ho provato diverse volte con array di byte generati casualmente.Ovviamente il processo di decodifica ignora semplicemente le newline o sono presenti o meno. Ho provato questo "funzionamento confermato" utilizzando com.sun.org.apache.xml.internal.security.utils.Base64 Altri encoder non testati.

+2

Questa risposta è super fantastica, vorrei poter sopravvivere per 10 volte. –

+1

buone pratiche o no, qualcuno dovrebbe commentare, ma tu hai salvato la mia giornata Mr. grazie – dakait

+0

Impressionante. Lavorando su un rapido utilizzo privato, e questo mi ha salvato dal dover smettere di cercare un codificatore Base64 di terze parti. – developerwjk

1

Da codificare frammento del VA ...

sostituire:

return new BASE64Encoder().encode(encVal); 

con:

return new android.util.Base64.encodeToString(encVal, Base64.NO_WRAP); 

per rimuovere la linea-break fuori del nostro risultato

import android.util.Base64; 

... 

return new BASE64.encodeToString(encVal, Base64.NO_WRAP); 
+0

Potresti elaborare un po 'la tua risposta? –

+0

Dallo snippet di codifica del VA, sostituiamo "return new BASE64Encoder(). Encode (encVal);" con "return new android.util.Base64.encodeToString (encVal, Base64.NO_WRAP);" per rimuovere l'interruzione di riga del nostro risultato. – user2955935

Problemi correlati