2012-04-23 15 views
5

Estoy tratando de implementar un codificador de cadena simple para ofuscar algunas partes de una cadena de URL (para evitar que un usuario las saque de red). Estoy utilizando el código casi idéntica a la muestra en el JCA guide, excepto:Evitar saltos de línea en cadena URL cifrada y codificada

  • utilizando DES (asumiendo que es un poco más rápido que AES, y requiere una clave más pequeña) y
  • base 64 es/decodificación de la cadena de asegúrese de que sea seguro para una URL.

Por razones que no puedo entender, la cadena de salida termina con saltos de línea, que presumo que no funcionarán. No puedo entender qué está causando esto. ¿Sugerencias sobre algo similar que sea más fácil o consejos sobre otros recursos para leer? Estoy encontrando todas las referencias de criptografía un poco sobre mi cabeza (y excesivo), pero una simple implementación ROT13 no funcionará porque quiero tratar con un juego de caracteres más grande (y no quiero perder el tiempo implementando algo que probablemente sea tengo problemas con personajes oscuros que no pensé).

entrada de la muestra (sin salto de línea):

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 

Salida de muestra (saltos de línea como se muestra a continuación):

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

mi codificar fragmento:

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

¿Intentó simplemente revertir su operación de codificación y ver si funciona ? – Snicolas

+0

¿De dónde viene esa clase BASE64Encoder? – leonbloy

+1

@leonbloy Estaba importando sun.misc.BASE64Decoder, que he encontrado gracias a [esta publicación] (http://stackoverflow.com/questions/2267036/work-sun-misc-base64encoder-decoder-for-getting- byte) no es una buena idea. – milletron

Respuesta

7

Base64 codificadores generalmente imponer una longitud máxima de línea (, fragmento), y agrega líneas nuevas cuando ne Caryary. Normalmente puede configurar eso, pero eso depende de la implementación del codificador en particular. Por ejemplo, la clase de Apache Commons tiene un atributo linelength, al ponerlo a cero (o negativo) deshabilita la separación de línea.

BTW: Estoy de acuerdo con la otra respuesta en que el DES no es aconsejable hoy. Además, ¿simplemente estás "ofuscando" o realmente encriptando? ¿Quién tiene la llave? Todo esto no me huele muy bien.

+0

Realmente es más ofuscante que el cifrado. Simplemente usando una cadena codificada como una "clave" en la clase de llamada (que es compartida por los servlets que generan y consumen las URL ofuscadas). Gracias por la ventaja de longitud de línea, también señalada por @Jerry Coffin – milletron

+0

Dado que el codificador Apache Commons dice "... está codificado para codificar/decodificar codificaciones de caracteres que son compatibles con el gráfico inferior ASCII 127", esto ganó ' No funciona, ya que tengo caracteres fuera de este rango. Necesito repensar todo este enfoque, piensa. – milletron

+0

"esto no funcionará ya que tengo caracteres fuera de este rango": lea atentamente: funciona con caracteres fuera de ASCII, simplemente que la codificación binaria no puede ser utf-16, pero puede ser utf-8, o iso-8859-1, etc. – leonbloy

1

Aunque no está relacionado a su pregunta real, DES es generalmente más lenta de AES (al menos en el software), por lo menos que realmente necesita para mantener la llave pequeña, AES es casi seguro que una mejor opción.

En segundo lugar, es perfectamente normal que el cifrado (DES o AES) produzca/produzca caracteres de nueva línea en su salida. Producir resultados sin ellos dependerá por completo del codificador de base 64, por lo que es donde claramente necesita mirar.

No es particularmente sorprendente ver una base 64 insertar caracteres de nueva línea a intervalos regulares en su salida. El uso más común para la codificación de base 64 es poner los datos sin procesar en algo así como el cuerpo de un correo electrónico, donde una línea realmente larga podría causar un problema. Para evitar eso, los datos se dividen en pedazos, normalmente no más de 80 columnas (y usualmente un poco menos). En este caso, las líneas nuevas deberían ignorarse, por lo que debería poder eliminarlas, si la memoria le sirve.

11

Simplemente realice base64Str = base64Str.replaceAll("(?:\\r\\n|\\n\\r|\\n|\\r)", "") en la cadena codificada.

Funciona bien cuando intenta decodificarlo de nuevo a bytes. Lo probé varias veces con matrices de bytes generadas al azar.Obviamente, el proceso de decodificación simplemente ignora las líneas nuevas, ya sea que estén presentes o no. He probado este "trabajo confirmado" utilizando com.sun.org.apache.xml.internal.security.utils.Base64 Otros codificadores no probados.

+2

Esta respuesta es súper increíble, ojalá pudiera votar 10 veces. –

+1

buenas prácticas o no, alguien debería comentar, pero me salvaste el día Sr. gracias – dakait

+0

Impresionante. Trabajando en una aplicación privada rápida, y esto me evitó tener que parar e ir a buscar un codificador Base64 de terceros. – developerwjk

1

De fragmento de codificación de la VA ...

reemplazar:

return new BASE64Encoder().encode(encVal); 

con:

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

para eliminar salto de línea fuera de nuestro resultado

import android.util.Base64; 

... 

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

¿Podría explicar un poco sobre su respuesta? –

+0

Desde el fragmento de codificación del VA, reemplazamos "return new BASE64Encoder(). Encode (encVal);" con "return new android.util.Base64.encodeToString (encVal, Base64.NO_WRAP);" para eliminar el salto de línea de nuestro resultado. – user2955935

Cuestiones relacionadas