tool tdes online length encrypt java encryption 3des

tdes - ¿Cómo uso el cifrado/descifrado 3DES en Java?



key generator 3des (5)

Aquí hay una clase de encriptación / descifrado estática muy simple sesgada en el castillo de Bouncy sin ningún ejemplo de relleno de José Luis Montes de Oca. Este usa "DESede / ECB / PKCS7Padding", así que no tengo que molestar el relleno manual.

package com.zenimax.encryption; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * * @author Matthew H. Wagner */ public class TripleDesBouncyCastle { private static String TRIPLE_DES_TRANSFORMATION = "DESede/ECB/PKCS7Padding"; private static String ALGORITHM = "DESede"; private static String BOUNCY_CASTLE_PROVIDER = "BC"; private static void init() { Security.addProvider(new BouncyCastleProvider()); } public static byte[] encode(byte[] input, byte[] key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException { init(); SecretKey keySpec = new SecretKeySpec(key, ALGORITHM); Cipher encrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); encrypter.init(Cipher.ENCRYPT_MODE, keySpec); return encrypter.doFinal(input); } public static byte[] decode(byte[] input, byte[] key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException { init(); SecretKey keySpec = new SecretKeySpec(key, ALGORITHM); Cipher decrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); decrypter.init(Cipher.DECRYPT_MODE, keySpec); return decrypter.doFinal(input); } }

Todos los métodos que escribo para codificar una cadena en Java utilizando 3DES no se pueden descifrar de nuevo a la cadena original. ¿Alguien tiene un fragmento de código simple que puede codificar y luego decodificar la cadena de nuevo a la cadena original?

Sé que estoy cometiendo un error muy tonto en algún lugar de este código. Esto es con lo que he estado trabajando hasta ahora:

** nota, no estoy devolviendo el texto BASE64 del método de encriptación, y no estoy descifrando base64 en el método de descifrado porque estaba tratando de ver si estaba cometiendo un error en la parte BASE64 del rompecabezas.

public class TripleDESTest { public static void main(String[] args) { String text = "kyle boon"; byte[] codedtext = new TripleDESTest().encrypt(text); String decodedtext = new TripleDESTest().decrypt(codedtext); System.out.println(codedtext); System.out.println(decodedtext); } public byte[] encrypt(String message) { try { final MessageDigest md = MessageDigest.getInstance("md5"); final byte[] digestOfPassword = md.digest("HG58YZ3CR9".getBytes("utf-8")); final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24); for (int j = 0, k = 16; j < 8;) { keyBytes[k++] = keyBytes[j++]; } final SecretKey key = new SecretKeySpec(keyBytes, "DESede"); final IvParameterSpec iv = new IvParameterSpec(new byte[8]); final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, iv); final byte[] plainTextBytes = message.getBytes("utf-8"); final byte[] cipherText = cipher.doFinal(plainTextBytes); final String encodedCipherText = new sun.misc.BASE64Encoder().encode(cipherText); return cipherText; } catch (java.security.InvalidAlgorithmParameterException e) { System.out.println("Invalid Algorithm"); } catch (javax.crypto.NoSuchPaddingException e) { System.out.println("No Such Padding"); } catch (java.security.NoSuchAlgorithmException e) { System.out.println("No Such Algorithm"); } catch (java.security.InvalidKeyException e) { System.out.println("Invalid Key"); } catch (BadPaddingException e) { System.out.println("Invalid Key");} catch (IllegalBlockSizeException e) { System.out.println("Invalid Key");} catch (UnsupportedEncodingException e) { System.out.println("Invalid Key");} return null; } public String decrypt(byte[] message) { try { final MessageDigest md = MessageDigest.getInstance("md5"); final byte[] digestOfPassword = md.digest("HG58YZ3CR9".getBytes("utf-8")); final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24); for (int j = 0, k = 16; j < 8;) { keyBytes[k++] = keyBytes[j++]; } final SecretKey key = new SecretKeySpec(keyBytes, "DESede"); final IvParameterSpec iv = new IvParameterSpec(new byte[8]); final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); decipher.init(Cipher.DECRYPT_MODE, key, iv); //final byte[] encData = new sun.misc.BASE64Decoder().decodeBuffer(message); final byte[] plainText = decipher.doFinal(message); return plainText.toString(); } catch (java.security.InvalidAlgorithmParameterException e) { System.out.println("Invalid Algorithm"); } catch (javax.crypto.NoSuchPaddingException e) { System.out.println("No Such Padding"); } catch (java.security.NoSuchAlgorithmException e) { System.out.println("No Such Algorithm"); } catch (java.security.InvalidKeyException e) { System.out.println("Invalid Key"); } catch (BadPaddingException e) { System.out.println("Invalid Key");} catch (IllegalBlockSizeException e) { System.out.println("Invalid Key");} catch (UnsupportedEncodingException e) { System.out.println("Invalid Key");} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }


Aquí hay una solución que usa la biblioteca javax.crypto y la biblioteca de códecs de Apache commons para codificar y decodificar en Base64:

import java.security.spec.KeySpec; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import org.apache.commons.codec.binary.Base64; public class TrippleDes { private static final String UNICODE_FORMAT = "UTF8"; public static final String DESEDE_ENCRYPTION_SCHEME = "DESede"; private KeySpec ks; private SecretKeyFactory skf; private Cipher cipher; byte[] arrayBytes; private String myEncryptionKey; private String myEncryptionScheme; SecretKey key; public TrippleDes() throws Exception { myEncryptionKey = "ThisIsSpartaThisIsSparta"; myEncryptionScheme = DESEDE_ENCRYPTION_SCHEME; arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT); ks = new DESedeKeySpec(arrayBytes); skf = SecretKeyFactory.getInstance(myEncryptionScheme); cipher = Cipher.getInstance(myEncryptionScheme); key = skf.generateSecret(ks); } public String encrypt(String unencryptedString) { String encryptedString = null; try { cipher.init(Cipher.ENCRYPT_MODE, key); byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT); byte[] encryptedText = cipher.doFinal(plainText); encryptedString = new String(Base64.encodeBase64(encryptedText)); } catch (Exception e) { e.printStackTrace(); } return encryptedString; } public String decrypt(String encryptedString) { String decryptedText=null; try { cipher.init(Cipher.DECRYPT_MODE, key); byte[] encryptedText = Base64.decodeBase64(encryptedString); byte[] plainText = cipher.doFinal(encryptedText); decryptedText= new String(plainText); } catch (Exception e) { e.printStackTrace(); } return decryptedText; } public static void main(String args []) throws Exception { TrippleDes td= new TrippleDes(); String target="imparator"; String encrypted=td.encrypt(target); String decrypted=td.decrypt(encrypted); System.out.println("String To Encrypt: "+ target); System.out.println("Encrypted String:" + encrypted); System.out.println("Decrypted String:" + decrypted); } }

Ejecutando los resultados del programa anterior con el siguiente resultado:

String To Encrypt: imparator Encrypted String:FdBNaYWfjpWN9eYghMpbRA== Decrypted String:imparator


Su código estaba bien, excepto el bit de codificación Base 64 (que mencionó que era una prueba), la razón por la cual la salida puede no tener sentido es que estaba visualizando una matriz de bytes sin procesar (al hacer toString () en una matriz de bytes devuelve su Referencia de Java, no la representación de cadenas de los contenidos ). Aquí hay una versión que se ha limpiado un poco y que imprime "kyle boon" como la cadena decodificada:

import java.security.MessageDigest; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class TripleDESTest { public static void main(String[] args) throws Exception { String text = "kyle boon"; byte[] codedtext = new TripleDESTest().encrypt(text); String decodedtext = new TripleDESTest().decrypt(codedtext); System.out.println(codedtext); // this is a byte array, you''ll just see a reference to an array System.out.println(decodedtext); // This correctly shows "kyle boon" } public byte[] encrypt(String message) throws Exception { final MessageDigest md = MessageDigest.getInstance("md5"); final byte[] digestOfPassword = md.digest("HG58YZ3CR9" .getBytes("utf-8")); final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24); for (int j = 0, k = 16; j < 8;) { keyBytes[k++] = keyBytes[j++]; } final SecretKey key = new SecretKeySpec(keyBytes, "DESede"); final IvParameterSpec iv = new IvParameterSpec(new byte[8]); final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, iv); final byte[] plainTextBytes = message.getBytes("utf-8"); final byte[] cipherText = cipher.doFinal(plainTextBytes); // final String encodedCipherText = new sun.misc.BASE64Encoder() // .encode(cipherText); return cipherText; } public String decrypt(byte[] message) throws Exception { final MessageDigest md = MessageDigest.getInstance("md5"); final byte[] digestOfPassword = md.digest("HG58YZ3CR9" .getBytes("utf-8")); final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24); for (int j = 0, k = 16; j < 8;) { keyBytes[k++] = keyBytes[j++]; } final SecretKey key = new SecretKeySpec(keyBytes, "DESede"); final IvParameterSpec iv = new IvParameterSpec(new byte[8]); final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding"); decipher.init(Cipher.DECRYPT_MODE, key, iv); // final byte[] encData = new // sun.misc.BASE64Decoder().decodeBuffer(message); final byte[] plainText = decipher.doFinal(message); return new String(plainText, "UTF-8"); } }


Tuve dificultades para descubrirlo y esta publicación me ayudó a encontrar la respuesta correcta para mi caso. Al trabajar con mensajes financieros como ISO-8583, los requisitos de 3DES son bastante específicos, por lo que para mi caso especial, las combinaciones "DESede / CBC / PKCS5Padding" no solucionaban el problema. Después de algunas pruebas comparativas de mis resultados con algunas calculadoras 3DES diseñadas para el mundo financiero, encontré el valor "DESede / ECB / Nopadding" más adecuado para la tarea específica.

Aquí hay una implementación de demostración de mi clase TripleDes (usando el proveedor Bouncy Castle)

import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Security; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.NoSuchPaddingException; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.jce.provider.BouncyCastleProvider; /** * * @author Jose Luis Montes de Oca */ public class TripleDesCipher { private static String TRIPLE_DES_TRANSFORMATION = "DESede/ECB/Nopadding"; private static String ALGORITHM = "DESede"; private static String BOUNCY_CASTLE_PROVIDER = "BC"; private Cipher encrypter; private Cipher decrypter; public TripleDesCipher(byte[] key) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException, InvalidKeyException { Security.addProvider(new BouncyCastleProvider()); SecretKey keySpec = new SecretKeySpec(key, ALGORITHM); encrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); encrypter.init(Cipher.ENCRYPT_MODE, keySpec); decrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER); decrypter.init(Cipher.DECRYPT_MODE, keySpec); } public byte[] encode(byte[] input) throws IllegalBlockSizeException, BadPaddingException { return encrypter.doFinal(input); } public byte[] decode(byte[] input) throws IllegalBlockSizeException, BadPaddingException { return decrypter.doFinal(input); } }


import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESedeKeySpec; import javax.crypto.spec.IvParameterSpec; import java.util.Base64; import java.util.Base64.Encoder; /** * * @author shivshankar pal * * this code is working properly. doing proper encription and decription note:- it will work only with jdk8 * * */ public class TDes { private static byte[] key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; private static byte[] keyiv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; public static String encode(String args) { System.out.println("plain data==> " + args); byte[] encoding; try { encoding = Base64.getEncoder().encode(args.getBytes("UTF-8")); System.out.println("Base64.encodeBase64==>" + new String(encoding)); byte[] str5 = des3EncodeCBC(key, keyiv, encoding); System.out.println("des3EncodeCBC==> " + new String(str5)); byte[] encoding1 = Base64.getEncoder().encode(str5); System.out.println("Base64.encodeBase64==> " + new String(encoding1)); return new String(encoding1); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static String decode(String args) { try { System.out.println("encrypted data==>" + new String(args.getBytes("UTF-8"))); byte[] decode = Base64.getDecoder().decode(args.getBytes("UTF-8")); System.out.println("Base64.decodeBase64(main encription)==>" + new String(decode)); byte[] str6 = des3DecodeCBC(key, keyiv, decode); System.out.println("des3DecodeCBC==>" + new String(str6)); String data=new String(str6); byte[] decode1 = Base64.getDecoder().decode(data.trim().getBytes("UTF-8")); System.out.println("plaintext==> " + new String(decode1)); return new String(decode1); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return "u mistaken in try block"; } private static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) { try { Key deskey = null; DESedeKeySpec spec = new DESedeKeySpec(key); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("desede/ CBC/PKCS5Padding"); IvParameterSpec ips = new IvParameterSpec(keyiv); cipher.init(Cipher.ENCRYPT_MODE, deskey, ips); byte[] bout = cipher.doFinal(data); return bout; } catch (Exception e) { System.out.println("methods qualified name" + e); } return null; } private static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) { try { Key deskey = null; DESedeKeySpec spec = new DESedeKeySpec(key); SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); deskey = keyfactory.generateSecret(spec); Cipher cipher = Cipher.getInstance("desede/ CBC/NoPadding");//PKCS5Padding NoPadding IvParameterSpec ips = new IvParameterSpec(keyiv); cipher.init(Cipher.DECRYPT_MODE, deskey, ips); byte[] bout = cipher.doFinal(data); return bout; } catch (Exception e) { System.out.println("methods qualified name" + e); } return null; } }