Java 3DES ECB NoPadding

在搞银联POS机的东东,略感头疼,搞了N久,还是终端-Hulk 给的方法解决了3DES加密解密的难题。

import java.security.Key;
import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

public class HuldMethod {

	public static void main(String[] args) throws Exception{
		
		//0123456789ABCDEFFEDCBA9876543210 给的是16字节的密钥,但要凑够24个字节,所以截取前面的8个
		//字节0123456789ABCDEF追加到密钥的后面
		//byte[] key = Util.HexString2Bytes("0123456789ABCDEFFEDCBA9876543210");
		byte[] key = Util.HexString2Bytes("0123456789ABCDEFFEDCBA98765432100123456789ABCDEF");
		byte[] data = Util.HexString2Bytes("1234567887654321");
		byte[] crypt = encrypt(data, key); // 3DES 加密
		System.out.println("加密后: " + Util.bytesToHexString(crypt));

		byte[] jiemi = decrypt(crypt, key);
		System.out.println("解密后: " + Util.bytesToHexString(jiemi));
		
		
	}
	
	/**
	 * 合并字节数组
	 * @param byte_1
	 * @param byte_2
	 * @return
	 */
	public static byte[] byteMerger(byte[] byte_1, byte[] byte_2) {
		byte[] byte_3 = new byte[byte_1.length + byte_2.length];
		System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
		System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
		return byte_3;
	}
    public static byte[] decrypt(byte[] crypt, byte[] key) throws Exception {
        Key k = toKey(key);
        Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, k);
        return cipher.doFinal(crypt);
    }
 
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        Key k = toKey(key);
        Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, k);
        return cipher.doFinal(data);
    }
 
    public static SecretKey toKey(byte[] key) throws Exception {
        KeySpec dks = new DESedeKeySpec(key);   
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        return keyFactory.generateSecret(dks);
    }
    
    public static String getPasswordByKey24(String account,String passord,String pingankey) throws Exception
    {
	   	 byte[] key = Util.HexString2Bytes(pingankey);
	     PinBlock pb = new PinBlock();
	     byte[] data = pb.process(passord,account);    
	     byte[] crypt = encrypt(data, key);  // 3DES 加密
	
	     return Util.bytesToHexString(crypt).toUpperCase();
    }
    
    public static String getPasswordByKey16(String account,String passord,String pingankey) throws Exception
    {
    	String Key8 = pingankey.substring(0,16);
    	String Key = pingankey+Key8;
	   	 byte[] key = Util.HexString2Bytes(Key);
	     PinBlock pb = new PinBlock();
	     byte[] data = pb.process(passord,account);    
	     byte[] crypt = encrypt(data, key);  // 3DES 加密
	
	     return Util.bytesToHexString(crypt).toUpperCase();
    }
    
    public static String decryptKey(String crypt, String pingankey) throws Exception {
    
    	String Key8 = pingankey.substring(0,16);
    	String Key = pingankey+Key8;    	
    	byte[] key = Util.HexString2Bytes(Key);
    	byte[] data = Util.HexString2Bytes(crypt);
    	
    	byte[] plain = decrypt(data, key);  // 3DES 解密
    	return Util.bytesToHexString(plain).toUpperCase();  
    }
}


用到了两个工具类

public class PinBlock {
	/**
	   * getPinBlock
	   * ��׼ANSI X9.8 Format�������ʺ���Ϣ����PIN BLOCK����
	   * PIN BLOCK ��ʽ���� PIN  ��λ���  ���ʺ�;
	   * @param pin String
	   * @param accno String
	   * @return byte[]
	   */
	  public byte[] process(String pin, String accno) {
	    byte arrAccno[] = getHAccno(accno);
	    byte arrPin[] = getHPin(pin);
	    byte arrRet[] = new byte[8];
	    //PIN BLOCK ��ʽ���� PIN  ��λ���  ���ʺ�;
	    for (int i = 0; i < 8; i++) {
	      arrRet[i] = (byte) (arrPin[i] ^ arrAccno[i]);
	    }
	    //Util.printHexString("PinBlock��", arrRet);
	    return arrRet;
	  }

	  /**
	   * getHPin
	   * ���������ת��
	   * PIN��ʽ
	   * BYTE 1 PIN�ij���
	   * BYTE 2 �C BYTE 3/4/5/6/7   4--12��PIN(ÿ��PINռ4��BIT)
	   * BYTE 4/5/6/7/8 �C BYTE 8   FILLER ��F�� (ÿ����F��ռ4��BIT)
	   * @param pin String
	   * @return byte[]
	   */
	  private byte[] getHPin(String pin) {
	    byte arrPin[] = pin.getBytes();
	    byte encode[] = new byte[8];
	    encode[0] = (byte) 0x06;
	    encode[1] = (byte) Util.uniteBytes(arrPin[0], arrPin[1]);
	    encode[2] = (byte) Util.uniteBytes(arrPin[2], arrPin[3]);
	    encode[3] = (byte) Util.uniteBytes(arrPin[4], arrPin[5]);
	    encode[4] = (byte) 0xFF;
	    encode[5] = (byte) 0xFF;
	    encode[6] = (byte) 0xFF;
	    encode[7] = (byte) 0xFF;
	    //Util.printHexString("encoded pin��", encode);
	    return encode;
	  }

	  /**
	   * getHAccno
	   * ���ʺŽ���ת��
	   * BYTE 1 �� BYTE 2  0X0000
	   * BYTE 3 �� BYTE 8 12�����ʺ�
	   * ȡ���ʺŵ���12λ�����������ұߵ�У��λ��������12λ�

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用Java进行DES解密的示例代码: ```java import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; public class DESUtil { private static final String ALGORITHM = "DES/ECB/NoPadding"; private static final String CHARSET = "UTF-8"; public static String decrypt(String key, String encryptedData) throws Exception { byte[] keyBytes = key.getBytes(CHARSET); byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "DES"); Cipher cipher = Cipher.getInstance(ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, CHARSET).trim(); } public static void main(String[] args) throws Exception { String key = "XcuAksWm"; String encryptedData = "sBICdEwB6Qs="; // MP1X46Zf String decryptedData = decrypt(key, encryptedData); System.out.println(decryptedData); // 输出解密后的数据 } } ``` 其中,`decrypt`方法实现了对加密数据的解密操作,输入参数为密钥和加密后的数据(base64编码),返回解密后的明文字符串。 在`main`方法中,我们传入了密钥和加密后的数据,调用`decrypt`方法进行解密,并输出解密后的明文字符串。 需要注意的是,由于加密时使用了NoPadding模式,因此在解密后需要手动去除填充的0x00字节。在上述代码中,我们使用了`trim`方法来去除字符串末尾的空白字符。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值