随着百度小程序的风头正劲,越来越多的站长投入到百度小程序的开发中来,但是开发过程中难免会碰到诸多问题无法自己解决,08-06小编发现百度用户:【shanetianxia】提出了一个关于“解密用户数据的Java示例代码解密错误”的问题,在问题中开发者shanetianxia对该问题做了如下阐述:
https://smartprogram.baidu.com/docs/develop/function/login_userdata/ 用java示例解密报错
预期:解密用户数据成功
实际结果:异常出错
js_code: afb2c034b62e2779e09915b20107b0e7NW
encrypted_data:DCHcuoVPkVHbWG2fzXj709SyygYRSMmbpyMnt1Mls86UqrqEeH00gd+yqi73hzdLXsrddtnk6sbdt+Kqt7/9/ckL/deP2uXS5a7x8hkVqxsnf5I02qi936jW6PeXXDKFaJoGu02voDVjALYT39jiQ56Br6QnZe5LHnfigpZaFyXuLa1EkGyQPb7U7uLCDr1jfPz3c/looyMB1ISExwNwzJOduICBX17zOEAYTrq33Ez23Mf1wsZzmbZ2v+3XBiaEf8p24uCEfEQeoTkF0kSsxOA4VYi+1mStii66v9hq/So=
iv:10fecb9e997d9a2191e3dw==
根据code 拿到了正确的 sessionkey和openid {“openid”:”z45QjEcuEsznnXXB1X9IW81mTt”,”session_key”:”10fecb9e997d9a2191e3d1c320b207e2″}
在下面代码:byte[] encrypted = Base64.decodeBase64(text); 解析错误,请帮忙看看,谢谢
提示java.lang.Exception: javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
/* * Copyright (C) 2018 Baidu, Inc. All Rights Reserved. */ package com.baidu.utils.secruity; import java.nio.charset.Charset; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; public class Demo { private static Charset CHARSET = Charset.forName("utf-8"); /** * 对密文进行解密 * * @param text 需要解密的密文 * * @return 解密得到的明文 * * @throws Exception 异常错误信息 */ public String decrypt(String text, String sessionKey,String ivStr) throws Exception { byte[] aesKey = Base64.decodeBase64(sessionKey + "="); byte[] original; try { Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES"); byte[] ivBytes = Base64.decodeBase64(ivStr); IvParameterSpec iv = new IvParameterSpec(ivBytes); cipher.init(Cipher.DECRYPT_MODE, keySpec, iv); byte[] encrypted = Base64.decodeBase64(text); original = cipher.doFinal(encrypted); } catch (Exception e) { throw new Exception(e); } String xmlContent; String fromClientId; try { // 去除补位字符 byte[] bytes = PKCS7Encoder.decode(original); // 分离16位随机字符串,网络字节序和ClientId byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20); int xmlLength = recoverNetworkBytesOrder(networkOrder); if (xmlLength > 65535) { /* * 注意:开发者解密加密数据出现乱码或者偶发OOM,一般是sessionKey过期导致 * * 开发者可以根据实际情况,改变判断值大小 */ throw new RuntimeException("aesKey invalid"); } xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET); fromClientId = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET); } catch (Exception e) { throw new Exception(e); } return xmlContent; } public static String getType(Object test) { return test.getClass().getName().toString(); } /** * 还原4个字节的网络字节序 * * @param orderBytes 字节码 * * @return sourceNumber */ private int recoverNetworkBytesOrder(byte[] orderBytes) { int sourceNumber = 0; int length = 4; int number = 8; for (int i = 0; i < length; i++) { sourceNumber <<= number; sourceNumber |= orderBytes[i] & 0xff; } return sourceNumber; } /** * 加密解密demo * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { String dy = "toMIrTrp2WovaM4RUoqsrBX4kR7p5JThrzY8bW4ZTBKm4YPRr0CfxY8ZZFwk0RJIPEVCVNebRuN3h6zOIHrHrjdvz5hcKkRfX3VO4OfoHJ3LiZv5uVRl6056iLBgNm+x2HY6T07A40aKeYJQDT3kmgdaAi3UB7NUlrEFUpAuZ2Tsm5B+bF3lnbmUzhskTCFE"; String sessionKey = "a28bea08d86e426f8d51e024194eae6f"; String iv = "a28bea08d86e426f8d51ew=="; Demo demo = new Demo(); String dd = demo.decrypt(dy, sessionKey, iv); System.out.println(dd); } } class PKCS7Encoder { static Charset CHARSET = Charset.forName("utf-8"); static int BLOCK_SIZE = 32; /** * 获得对明文进行补位填充的字节. * * @param count 需要进行填充补位操作的明文字节个数 * * @return 补齐用的字节数组 */ static byte[] encode(int count) { // 计算需要填充的位数 int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); if (amountToPad == 0) { amountToPad = BLOCK_SIZE; } // 获得补位所用的字符 char padChr = chr(amountToPad); String tmp = new String(); for (int index = 0; index < amountToPad; index++) { tmp += padChr; } return tmp.getBytes(CHARSET); } /** * 删除解密后明文的补位字符 * * @param decrypted 解密后的明文 * * @return 删除补位字符后的明文 */ static byte[] decode(byte[] decrypted) { int pad = (int) decrypted[decrypted.length - 1]; if (pad < 1 || pad > 32) { pad = 0; } return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); } /** * 将数字转化成ASCII码对应的字符,用于对明文进行补码 * * @param a 需要转化的数字 * * @return 转化得到的字符 */ static char chr(int a) { byte target = (byte) (a & 0xFF); return (char) target; } }
注:以上是百度小程序开发者:”shanetianxia”对于本问题的一些阐述,这里做一个引用,我们将实时关注百度小程序助手对该问题提出的解决方案。
【08-09】百度官方对用户shanetianxia提出的解密用户数据的Java示例代码解密错误给予如下回复
您好,解密用户数据的Java示例代码解密错误的问题,请您这边检查下解密时候输入的数据是否正确,是否有多加空格之类的错误,如果检查没有输入错误请再次反馈谢谢~
百度智能小程序开源联盟对于整个行业而言是一次机遇,让所有人都有机会享受到小程序所到来的红利。另一方面,对于百度自身而言,智能小程序开源联盟或许是其又一次业绩腾飞的潜在动力
如果您也在使用百度小程序,请关注我们,如果您有关于百度小程序的使用问题请联系我们,或者去百度小程序平台找官方人员给予解决,相信百度在小程序上的发力会是一个里程碑!