java - javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher -
i'm working on project i'm doing encryption, picked key , cryptographer aes , step base64. problem happens @ time of decrypting base64 aes , aes , return string. below error , code
import java.io.unsupportedencodingexception; import java.security.invalidkeyexception; import java.security.nosuchalgorithmexception; import java.util.base64; import javax.crypto.*; import javax.crypto.spec.*; public class criptografia { byte[] chave = "chave de 16bytes".getbytes(); public string encriptaaes(string chavecriptografada) throws invalidkeyexception, illegalblocksizeexception, badpaddingexception, unsupportedencodingexception { try { cipher cipher = cipher.getinstance("aes"); byte[] mensagem = chavecriptografada.getbytes(); cipher.init(cipher.encrypt_mode, new secretkeyspec(chave, "aes")); chavecriptografada = cipher.dofinal(mensagem).tostring(); chavecriptografada =base64.geturlencoder().encodetostring(chavecriptografada.getbytes("utf-8")); } catch (nosuchalgorithmexception | nosuchpaddingexception e) { e.printstacktrace(); } return chavecriptografada; } public string descriptografaaes(string chavecriptografada) throws nosuchalgorithmexception, nosuchpaddingexception, illegalblocksizeexception, badpaddingexception, unsupportedencodingexception{ cipher cipher = cipher.getinstance("aes"); byte[] base64decodedbytes = base64.geturldecoder().decode(chavecriptografada); chavecriptografada= base64decodedbytes.tostring(); try { cipher.init(cipher.decrypt_mode, new secretkeyspec(this.chave, "aes")); byte[] decrypted = cipher.dofinal(chavecriptografada.getbytes("utf-8")); chavecriptografada=decrypted.tostring(); } catch (invalidkeyexception e) { e.printstacktrace(); } return chavecriptografada; } } exception in thread "main" javax.crypto.illegalblocksizeexception: input length must multiple of 16 when decrypting padded cipher @ com.sun.crypto.provider.ciphercore.dofinal(ciphercore.java:922) @ com.sun.crypto.provider.ciphercore.dofinal(ciphercore.java:833) @ com.sun.crypto.provider.aescipher.enginedofinal(aescipher.java:446) @ javax.crypto.cipher.dofinal(cipher.java:2165) @ criptografia.descriptografaaes(criptografia.java:47) @ run.main(run.java:15)
i'm sharing precious encryption class english friend.
package encriptacion; import javax.crypto.*; import java.io.*; import java.nio.*; import java.nio.channels.*; import javax.crypto.spec.*; public class encriptadoraes { private secretkey clavesecreta=null; private final int aes_keylength = 128; private ivparameterspec iv=null; public encriptadoraes() throws exception{ //generariv(); if(new file("initvectoraes.iv").exists()){ this.iv=new ivparameterspec(obteneriv()); } } public void setclavesecreta(string clave){ this.clavesecreta=generarclavesecreta(clave); } public void guardarclave(string clave,string ruta)throws exception{ try{ byte[]bytesclave=generarclavesecreta(clave).getencoded(); filechannel canalsalida=new randomaccessfile(new file(ruta), "rw").getchannel(); bytebuffer buffersalida=bytebuffer.wrap(bytesclave); canalsalida.write(buffersalida); canalsalida.close(); }catch(exception ex){ throw new exception("no se pudo guardar la clave\n"+ex); } } public secretkey cargarclave(string ruta)throws exception{ try{ file archivo=new file(ruta); byte[]bytesclave=new byte[(int)archivo.length()]; filechannel canalentrada=new randomaccessfile(archivo, "r").getchannel(); bytebuffer bufferentrada=bytebuffer.allocate(bytesclave.length); canalentrada.read(bufferentrada); bufferentrada.flip(); bufferentrada.get(bytesclave); canalentrada.close(); return new secretkeyspec(bytesclave, "aes"); }catch(exception ex){ throw new exception("no se pudo cargar la clave secreta\n"+ex); } } public void encriptararchivo(string ruta,secretkey clave) throws exception{ file archivo=null; try { archivo=new file(ruta); if(archivo.isfile()&&archivo.exists()&&archivo.length()<=700248752){ //lectura byte[] bytesarchivo=new byte[(int)archivo.length()]; int tamañobloque=aes_keylength/8; int numbloques=((int)archivo.length()%tamañobloque==0)?(int)archivo.length()/tamañobloque:((int)archivo.length()/tamañobloque)+1; int tamañoencriptado=((bytesarchivo.length/tamañobloque)+1)*tamañobloque; filechannel canalentrada=new randomaccessfile(archivo, "r").getchannel(); bytebuffer bufferentrada=bytebuffer.allocate((int)archivo.length()); canalentrada.read(bufferentrada); bufferentrada.flip(); bufferentrada.get(bytesarchivo); canalentrada.close(); //cifrado clave simétrica bytebuffer buffersalida=bytebuffer.allocate(tamañoencriptado); cipher cifradoraes = cipher.getinstance("aes/cbc/pkcs5padding"); cifradoraes.init(cipher.encrypt_mode, clave,this.iv); buffersalida.put(cifradoraes.dofinal(bytesarchivo)); buffersalida.flip(); //escritura if(archivo.delete()){ filechannel canalsalida=new randomaccessfile(archivo,"rw").getchannel(); canalsalida.write(buffersalida); canalsalida.close(); }else throw new exception("no se pudo borrar el archivo "+archivo.getname()+", si lo tiene abierto, ciérrelo."); }else{ if(!archivo.exists())throw new exception("el archivo "+archivo.getname()+" no existe"); if(!archivo.isfile())throw new exception("no puede encriptar un directorio, trate\nde comprimirlo antes para luego encriptar los archivos"); if(archivo.length()>700248752)throw new exception("no se puede encriptar el archivo "+archivo.getname()+" porque ha superado el tamaño máximo\nde capacidad de memoria del jvm"); } } catch (exception ex){ throw new exception("hubo un error al encriptar el archivo\n"+ archivo.getname() +"\n"+ex); } } public void desencriptararchivo(string ruta,secretkey clave)throws exception{ file archivoencriptado=null; try{ archivoencriptado=new file(ruta); if(archivoencriptado.exists()){ //lectura byte[]bytesarchivoencriptado=new byte[(int)archivoencriptado.length()]; int tamañobloque=aes_keylength/8; int numbloques=((int)archivoencriptado.length()%tamañobloque==0)?(int)archivoencriptado.length()/tamañobloque:((int)archivoencriptado.length()/tamañobloque)+1; filechannel canalentrada=new randomaccessfile(archivoencriptado, "r").getchannel(); bytebuffer bufferentrada=bytebuffer.allocate((int)archivoencriptado.length()); canalentrada.read(bufferentrada); bufferentrada.flip(); bufferentrada.get(bytesarchivoencriptado); canalentrada.close(); //descrifrado bytebuffer buffersalida=bytebuffer.allocate((int)archivoencriptado.length()); if(comprobarkeys(clave)){ cipher descifradoraes = cipher.getinstance("aes/cbc/pkcs5padding"); descifradoraes.init(cipher.decrypt_mode,clave,this.iv); buffersalida.put(descifradoraes.dofinal(bytesarchivoencriptado)); buffersalida.flip(); } else{ system.gc(); throw new exception("la clave ingresada es incorrecta"); } //escritura if(archivoencriptado.delete()){ filechannel canalsalida=new randomaccessfile(ruta, "rw").getchannel(); canalsalida.write(buffersalida); canalsalida.close(); }else throw new exception("no se pudo eliminar el archivo "+archivoencriptado.getname()+", si lo tiene abierto, ciérrelo."); }else{ if(!archivoencriptado.exists())throw new exception("el archivo "+archivoencriptado.getname()+" no existe"); } } catch (exception ex){ system.gc(); throw new exception("hubo un error al desencriptar\n"+archivoencriptado.getname()+":\n"+ex.getmessage()); } } public secretkey generarclavesecreta(string clave){ byte[]key=rellenarbytesclave(clave); secretkey clavegenerada=new secretkeyspec(key, "aes"); return clavegenerada; } private byte[] rellenarbytesclave(string clave){ byte[]key=clave.getbytes(); while(key.length!=aes_keylength/8){ if(key.length<aes_keylength/8){ clave+="0"; key=clave.getbytes(); } if(key.length>aes_keylength/8){ clave=clave.substring(0,aes_keylength/8); key=clave.getbytes(); } } return key; } private boolean comprobarkeys(secretkey clave){ return this.clavesecreta.equals(clave); } public void generariv() throws exception{ try{ byte[]vector={1,6,1,2,1,9,9,7,7,9,9,1,2,1,6,1}; filechannel canalsalida=new randomaccessfile(new file("initvectoraes.iv"), "rw").getchannel(); mappedbytebuffer buffersalida=canalsalida.map(filechannel.mapmode.read_write, 0, 16); buffersalida.put(vector); buffersalida.force(); canalsalida.close(); }catch(exception ex){ throw new exception("error al generar el vector de inicialización de aes\n"+ex.getmessage()); } } private byte[]obteneriv()throws exception{ byte[]vectorcargado=null; try{ filechannel canalentrada=new randomaccessfile(new file("initvectoraes.iv"), "r").getchannel(); mappedbytebuffer bufferentrada=canalentrada.map(filechannel.mapmode.read_only, 0, 16); vectorcargado=new byte[16]; bufferentrada.get(vectorcargado); bufferentrada.load(); canalentrada.close(); } catch(exception ex){ throw new exception("error al obtener el vector de inicialización de aes\n"+ex.getmessage()); } return vectorcargado; } }
edit code doesn't solve problem think in way
byte[] chave = "chave de 16bytes".getbytes(); ivparameterspec iv = new ivparameterspec(new byte[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}); string test = "test"; public string encriptaaes(string chavecriptografada) throws invalidkeyexception, illegalblocksizeexception, badpaddingexception, unsupportedencodingexception, invalidalgorithmparameterexception { try { cipher cipher = cipher.getinstance("aes/cbc/pkcs5padding"); system.out.println("mensaje: "+chavecriptografada); byte[] mensagem = chavecriptografada.getbytes(); cipher.init(cipher.encrypt_mode, new secretkeyspec(chave, "aes"), this.iv); chavecriptografada = new string(cipher.dofinal(mensagem)); system.out.println("mensaje encriptado: "+chavecriptografada); chavecriptografada = datatypeconverter.printbase64binary(chavecriptografada.getbytes()); this.test = datatypeconverter.printbase64binary(test.getbytes()); system.out.println("test: "+test); } catch (nosuchalgorithmexception | nosuchpaddingexception e) { e.printstacktrace(); } return chavecriptografada; } public string descriptografaaes(string chavecriptografada) throws nosuchalgorithmexception, nosuchpaddingexception, illegalblocksizeexception, badpaddingexception, unsupportedencodingexception, invalidalgorithmparameterexception { cipher cipher = cipher.getinstance("aes/cbc/pkcs5padding"); system.out.println("mensaje encriptado con base 64: "+chavecriptografada); byte[] base64decodedbytes = datatypeconverter.parsebase64binary(chavecriptografada); this.data=new string(datatypeconverter.parsebase64binary(this.data)); system.out.println("test: "+test); system.out.println("mensaje encriptado: "+new string(base64decodedbytes)); try { cipher.init(cipher.decrypt_mode, new secretkeyspec(this.chave, "aes") , this.iv); byte[] decrypted = cipher.dofinal(base64decodedbytes); chavecriptografada = new string(decrypted); } catch (invalidkeyexception e) { e.printstacktrace(); } return chavecriptografada; } public static void main(string[] args) throws exception{ aescipher cipher = new aescipher(); string mensajeencriptado = cipher.encriptaaes("mensaje"); system.out.println("mensaje encriptado con base 64: "+mensajeencriptado); system.out.println("mensaje desencriptado: "+cipher.descriptografaaes(mensajeencriptado)); }
Comments
Post a Comment