文章目录
- 随着百度小程序的风头正劲,越来越多的站长投入到百度小程序的开发中来,但是开发过程中难免会碰到诸多问题无法自己解决,08-06小编发现百度用户:【shanetianxia】提出了一个关于“解密用户数据的Java示例代码解密错误”的问题,在问题中开发者shanetianxia对该问题做了如下阐述:
- 问题类型:bug
- 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示例代码解密错误的问题,请您这边检查下解密时候输入的数据是否正确,是否有多加空格之类的错误,如果检查没有输入错误请再次反馈谢谢~
- 百度智能小程序开源联盟对于整个行业而言是一次机遇,让所有人都有机会享受到小程序所到来的红利。另一方面,对于百度自身而言,智能小程序开源联盟或许是其又一次业绩腾飞的潜在动力 如果您也在使用百度小程序,请关注我们,如果您有关于百度小程序的使用问题请联系我们,或者去百度小程序平台找官方人员给予解决,相信百度在小程序上的发力会是一个里程碑!
随着百度小程序的风头正劲,越来越多的站长投入到百度小程序的开发中来,但是开发过程中难免会碰到诸多问题无法自己解决,08-06小编发现百度用户:【shanetianxia】提出了一个关于“解密用户数据的Java示例代码解密错误”的问题,在问题中开发者shanetianxia对该问题做了如下阐述:
- 问题类型:bug
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;
}
}
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示例代码解密错误的问题,请您这边检查下解密时候输入的数据是否正确,是否有多加空格之类的错误,如果检查没有输入错误请再次反馈谢谢~
百度智能小程序开源联盟对于整个行业而言是一次机遇,让所有人都有机会享受到小程序所到来的红利。另一方面,对于百度自身而言,智能小程序开源联盟或许是其又一次业绩腾飞的潜在动力
如果您也在使用百度小程序,请关注我们,如果您有关于百度小程序的使用问题请联系我们,或者去百度小程序平台找官方人员给予解决,相信百度在小程序上的发力会是一个里程碑!