java转python推荐算法_Java DES算法转Python3的坑

参考博客:https://www.cnblogs.com/Tommy-Yu/p/5867181.html

今天写mock遇到一个比较坑的事情,Java加密的Python解不了密,具体看一下代码:

Java代码:

ContractedBlock.gif

ExpandedBlockStart.gif

1 packagecom.vcredit.entrustdelegator.utils;2

3 importjavax.crypto.Cipher;4 importjavax.crypto.SecretKey;5 importjavax.crypto.SecretKeyFactory;6 importjavax.crypto.spec.DESKeySpec;7 importjava.nio.charset.StandardCharsets;8 importjava.security.SecureRandom;9

10

11 public classEncrypt {12

13 /**

14 * 解密报文15 *16 *@paramvalue 密文17 *@paramkey 密钥18 *@return解密明文19 *@throwsException 异常20 */

21 public static String decrypt3DES(String value, String key) throwsException {22 return newString(decrypt(hex2byte(value.getBytes()), key.getBytes()), StandardCharsets.UTF_8);23 }24

25

26 /**

27 * 加密报文28 *29 *@paramvalue 明文30 *@paramkey 密钥31 *@return加密报文32 *@throwsException 异常33 */

34 public static String encrypt3DES(String value, String key) throwsException {35 returnbyte2hex(encrypt(value.getBytes(StandardCharsets.UTF_8), key.getBytes()));36 }37

38 private static byte[] hex2byte(byte[] buffer) {39 if (buffer.length % 2 != 0) {40 throw new IllegalArgumentException("长度不是偶数");41 } else{42 byte[] var1 = new byte[buffer.length / 2];43

44 for (int var2 = 0; var2 < buffer.length; var2 += 2) {45 String var3 = new String(buffer, var2, 2);46 var1[var2 / 2] = (byte) Integer.parseInt(var3, 16);47 }48

49 returnvar1;50 }51 }52

53 private static String byte2hex(byte[] buffer) {54 StringBuilder var1 = newStringBuilder();55 for (byteaBuffer : buffer) {56 String var2;57 if ((var2 = Integer.toHexString(aBuffer & 255)).length() == 1) {58 var1.append("0").append(var2);59 } else{60 var1.append(var2);61 }62 }63 returnvar1.toString().toUpperCase();64 }65

66 private static byte[] encrypt(byte[] src, byte[] key) throwsException {67 SecureRandom var2 = newSecureRandom();68 DESKeySpec key1 = newDESKeySpec(key);69 SecretKey key2 = SecretKeyFactory.getInstance("DES").generateSecret(key1);70 Cipher var3;71 (var3 = Cipher.getInstance("DES")).init(1, key2, var2);72 returnvar3.doFinal(src);73 }74

75 private static byte[] decrypt(byte[] src, byte[] key) throwsException {76 SecureRandom var2 = newSecureRandom();77 DESKeySpec key1 = newDESKeySpec(key);78 SecretKey key2 = SecretKeyFactory.getInstance("DES").generateSecret(key1);79 Cipher var3;80 (var3 = Cipher.getInstance("DES")).init(2, key2, var2);81 returnvar3.doFinal(src);82 }83 }

View Code

坑一:3DES

从上面的代码看解密函数是decrypt3DES,“3DES”让人以为是DES3算法,其实Java中的3DES对应的是“DESede”,于是利用Python的DES3算法解密,结果解不出来。这里其实用的还是DES算法。

坑二:DES

上面代码写的是getInstance("DES"),没有指明具体是什么算法,按照默认的来了,Java默认算法应该是DES/ECB/PKCS5Padding,Python我也用默认的了,还好默认的算法和Java一样,不过这里编码的时候最好明确指出,避免歧义。

坑三:Java的DES对key没有检查(参考的博客中有说明,写的很给力,很到位,一针见血)

如果key大于8位,则默认截取前8位用来加密!不报错!

但是Python中会报错,所以一开始用DES算法,看到报错了就觉得是算法用错了,然后用DES3算法,坑啊。

最后还是用DES算法,密码截取前8位,然后解密成功了!

对应Python代码:

ContractedBlock.gif

ExpandedBlockStart.gif

1 from Crypto.Cipher importDES2 importbinascii3

4 defdes_decode(data, key):5 """aes解密6 :param key:7 :param data:8 """

9 cipher =DES.new(key)10 result2 = binascii.a2b_hex(data) #十六进制还原成二进制

11 decrypted =cipher.decrypt(result2)12 print(decrypted)13 return decrypted.rstrip(b'\0') #解密完成后将加密时添加的多余字符'\0'删除

14

15

16 defaes_encrypt(data, key):17 """des加密函数,如果data不是16的倍数【加密文本data必须为16的倍数!】,那就补足为16的倍数18 :param key:19 :param data:20 """

21 cipher =DES.new(key)22 block_size =DES.block_size23 #判断data是不是16的倍数,如果不是用b'\0'补足

24 if len(data) % block_size !=0:25 add = block_size - (len(data) %block_size)26 else:27 add =028 data += b'\x03' *add29 encrypted = cipher.encrypt(data) #des加密

30 result = binascii.b2a_hex(encrypted) #b2a_hex encode 将二进制转换成16进制

31 return result

View Code

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值