场景

  • 对接一个第三方api接口,其中签名部分用的是JDK8的编码。我们线上采用JDK7,导致项目无法编译
  • 替换编解码部分为1.7的代码,然后签名又不对
  • 所以坑就在这里,结论,1.7的编解码有换行符导致签名失败

贴代码

import sun.misc.BASE64Decoder;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64; public class Base64EncodeDemo { public static final String CHARSET_UTF_8 = "UTF-8";
public static final String ALGORITHM_RSA = "RSA";
public static final String ALGORITHM_SHA1_WITH_RSA = "SHA1withRSA";
private static String signWithRSAJdk7(String source, String privateKey, String algorithm) {
String result = null;
try {
// 修改为 1.7语法
// PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(new BASE64Decoder().decodeBuffer(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
PrivateKey pk = keyFactory.generatePrivate(spec);
Signature signature = Signature.getInstance(algorithm);
signature.initSign(pk);
signature.update(source.getBytes(CHARSET_UTF_8)); // 修改为 1.7语法
//result = Base64.getEncoder().encodeToString(signature.sign());
result = new sun.misc.BASE64Encoder().encode(signature.sign());
System.out.println("jdk7解码签名换行符去掉前:"+result); // 1.7语法需要去掉换行符 这里是重点
result = result.replaceAll("\\n","");
System.out.println("jdk7解码签名换行符去掉后:"+result);
} catch (Exception e) {
System.out.println("RSA 签名出错!");
e.printStackTrace();
}
return result;
} private static String signWithRSAJdk8(String source, String privateKey, String algorithm) {
String result = null;
try {
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
PrivateKey pk = keyFactory.generatePrivate(spec);
Signature signature = Signature.getInstance(algorithm);
signature.initSign(pk);
signature.update(source.getBytes(CHARSET_UTF_8));
result = Base64.getEncoder().encodeToString(signature.sign());
System.out.println("jdk8解码签名:"+result);
} catch (Exception e) {
System.out.println("RSA 签名出错!");
e.printStackTrace();
}
return result;
} public static void main(String[] args) throws Exception {
String source = "app_id=89be0bb80a7a4e219b4011168c478f0c&biz_content={\"user_id\":\"17681865480\",\"idcard\":\"09612707419874225X\",\"name\":\"张三\",\"mobile\":\"17681865480\"}&format=JSON&method=moxie.api.risk.magicwand3.enhance-multi-info&sign_type=RSA&timestamp=1567593061041&version=1.0"; String privatekey= "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDjAKaU7DbXOMoa63pF1ArcyMPWmMxmmfpBlewFHDnqFee5Gm3XdLR+fvGj+ZwddEx27ZJkkjVoXmk1/NqT+9nFXvXSctfHu6OsmYaWguCCHDjMLzuWKhuTtFohFUJQLIyfuVImzGKPv1WMoPsjouz1trTXHwpF5oj0mqI1B0HZDBsb55Dyl3DkfIaZBkr7s0tuJ/LBIhengMp2gBc9d61Qr1S6mSAv1Hj6IrL34gkZv0U0+bdDO227/r14KS4MTaHudYM7fb43f0+VEcBXUKnQgR+f6yCq67JJyPaPQYtvrf+J6azrr1+hlX6FFGWNYwaKRblgg+b5ICw5hrR2H97LAgMBAAECggEAPH565isA/mAC9COWxS8Z6faSwgicSCd2mq3SZRY9lNVbmGejqAxQ4XkA+lrVsL/CdNsg7S5Nj0/BqAKHWXJ/eWqyBfBW8sJdfuy3AjtEi0fsFvXrYjw8dyNT9YcN0gHdQ9+GNhK3nWk26jAoXTnY/i4/iSibez9RdiYTXiBd+vIPXC/KpjyN8GXiDNg2Zc9aSK6M7Bqvy5w7QDyl+YHw55DIAjdXYkGR645xO3rhMaLcQ1SiUN0lvjKqGaHIjSYBPRjPuk4GFz6Ews0d+xdl3cMNodVosx3yNjKLTSYbJlwIYrcSMlBDjN3h6ZwY4znrehNuWAjhUvn0SI2NUupRAQKBgQD7BLyJXWsItGZPFTa8KBlg1GHphzmFXO6izZNb7CQPEklyDYKsrU2ZgMWtNJ2vDJ2d8PyzO5qILp8WUFOKgQTK7NJNemH1c2dcRVINRgiK5wN7xwp4mpm396X8flbArYYkHFXzFrt62DeJtvOWDgnUTETA/fvs2HdbUuQgLYBzSwKBgQDngeeTkKumR4NAFD7pC6galxB1vlzl3cAYQyCPE/DNo9INX+TmFPH1/JrSwSPUqC6KBTIJ2zkUpJm1XpGb4QZnlx4xNWwpjE+1fpjjer1a60t9V7Jur2DOiR83kzhE7NJ2ymnVv94v9wje1yhDnMyHY9KOppWeSIoam6XSB8+SgQKBgHHJd92c50QO4sG+kA1C8B4gqDHABqcZtWM/ZSkqJj5ev8Rfs3irJp4K7ZDSZRhQ07Ig56wnvKk22Q64YuZKDe4e5EYS0Az/vz7ofYVe1ciBZ+bYFzsMedoW/Ls0WgcFoeUEo0GKcHoDQUnAETNYMcR2vkPt3iFDDvfq31Zmye95AoGBALoQ1U/ryZnGBj49R2bEoKJmYatQiZeSR274nLWCIFsW3J81QGKP2PyMvt6+ro6fcXAqxtHXKSRnOsbjsAHptN0TPwfr2Pf3tqS3kCfcoU3uqOif0GBXgmXdHYLsRyBWer1Q6AkMwYYpdS6tHMZiwpvaZgOS7dOel6jVCkwpTPKBAoGBALu3R6ABaZx8c4C56ucL79akf1iw7s/3tpS3h3FJ5NzNeovtkmCuHosFWQkA4VKXQvL0S1zwWVd9/YJot5q05o5xn13yDhhmXqd8Da+ZMQJH0PMMyVlKF9tj7o6G5ZhFCTqZdVDdKE05De89d9ybNH3dGWU4ZycfbRa3pHmRuaHO";
String sign7 = signWithRSAJdk7(source, privatekey, ALGORITHM_SHA1_WITH_RSA);
String sign8 = signWithRSAJdk8(source, privatekey, ALGORITHM_SHA1_WITH_RSA);
// System.out.println(msg);
System.out.println("--------------");
System.out.println(sign7.equals(sign8));
}
}
  • 运行结果:
jdk7解码签名换行符去掉前:QXEvl/xDLanJ6GfB+eeZbawiKZwF3m1HzUr6r0GIk7DtWzI1GlOLt2au5aeqiIREwEi2sErRU/gU
HCJFH1h1SfhADsw1i0xEC3C9lBU+SQCy8asEYZKnLMEsodVB2XhpBo0VkbR2dQad06kfPZoQ8qD5
jTs/3xVJswATiGIVw7tGZaTO0VUwTt2v091MRMq3L80dg765QH2JMc/VzVoVCbYzcElzdwi9tNme
zkzqtRnWIwCkc6gwfTsr+3mh4zIfyeB78/vTfdY84tYxh0Lxy1PXKP4SBUktaGUvuKDDsnycpoMK
hCJU/WgCsmBe4Aj6+4IbnK2gUSMBOba06Cm6cA==
jdk7解码签名换行符去掉后:QXEvl/xDLanJ6GfB+eeZbawiKZwF3m1HzUr6r0GIk7DtWzI1GlOLt2au5aeqiIREwEi2sErRU/gUHCJFH1h1SfhADsw1i0xEC3C9lBU+SQCy8asEYZKnLMEsodVB2XhpBo0VkbR2dQad06kfPZoQ8qD5jTs/3xVJswATiGIVw7tGZaTO0VUwTt2v091MRMq3L80dg765QH2JMc/VzVoVCbYzcElzdwi9tNmezkzqtRnWIwCkc6gwfTsr+3mh4zIfyeB78/vTfdY84tYxh0Lxy1PXKP4SBUktaGUvuKDDsnycpoMKhCJU/WgCsmBe4Aj6+4IbnK2gUSMBOba06Cm6cA==
jdk8解码签名:QXEvl/xDLanJ6GfB+eeZbawiKZwF3m1HzUr6r0GIk7DtWzI1GlOLt2au5aeqiIREwEi2sErRU/gUHCJFH1h1SfhADsw1i0xEC3C9lBU+SQCy8asEYZKnLMEsodVB2XhpBo0VkbR2dQad06kfPZoQ8qD5jTs/3xVJswATiGIVw7tGZaTO0VUwTt2v091MRMq3L80dg765QH2JMc/VzVoVCbYzcElzdwi9tNmezkzqtRnWIwCkc6gwfTsr+3mh4zIfyeB78/vTfdY84tYxh0Lxy1PXKP4SBUktaGUvuKDDsnycpoMKhCJU/WgCsmBe4Aj6+4IbnK2gUSMBOba06Cm6cA==
--------------
true

结论

  • JDK1.7 编解码
编码
new sun.misc.BASE64Encoder().encode(byte[] array)
解码
new BASE64Decoder().decodeBuffer(String str)
  • JDK1.8 编解码
编码
Base64.getEncoder().encodeToString(byte[] array)
解码
Base64.getDecoder().decode(String str)
  • 注意换行这个坑
  • 1.8 变单例,线程安全提升了

JDK Base64编解码1.7和1.8的坑的更多相关文章

  1. Delphi Base64 编解码函数

    Delphi 自带 Base64 编解码的单元, EncdDecd这个单元提供两套四个公开函数: 对流的编解码:procedure EncodeStream(Input, Output: TStrea ...

  2. ios Base64编解码工具类及使用

    为了避免明码传递http内容,可以用base64编码后传输,收到方再解码,也方便了2进制数据的字符串式传输. 对于ios来说,google给提供了一个很好的工具类,方便进行base64编解码,当然也可 ...

  3. Java实现BASE64编解码

    Java实现BASE64编解码 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs BASE64和其它类似的编码算法通经常使用于转换二进制数据为文本数据,其目 ...

  4. Delphi 自带的 Base64 编解码函数

    今天帮别人解决一个关于 Base64 编解码的问题,竟然发现 Delphi 自带了 Base64 编解码的单元,叫 EncdDecd,这名字很拗口而且不直观,估计这是一直很少人关注和知道的原因. 这个 ...

  5. openssl命令行Base64编解码

    openssl对base64编解码的规范支持较差,用它编解码的结果别的语言如php处理很不方便,注意的几点整理如下 1,如果php加密结果做base64编码长度小于64,则需要添加一个换行符opens ...

  6. python rsa 加密解密 (编解码,base64编解码)

    最近有需求,需要研究一下RSA加密解密安全:在网上百度了一下例子文章,很少有文章介绍怎么保存.传输.打印加密后的文本信息,都是千篇一律的.直接在一个脚本,加密后的文本信息赋于变量,然后立马调用解密.仔 ...

  7. python base64 编解码,转换成Opencv,PIL.Image图片格式

    二进制打开图片文件,base64编解码,转成Opencv格式: # coding: utf-8 import base64 import numpy as np import cv2 img_file ...

  8. EasyDarwin开源流媒体云平台中boost Base64编解码后与源长度不匹配的bug

    本文转自EasyDarwin团队Alex的博客:http://blog.csdn.net/cai6811376 EasyDarwin云平台中部分协议使用了Base64编码昨晚报文通信的载体.比如在对摄 ...

  9. C++,Base64编解码字符串或文件

    参考链接:在C语言中使用libb64进行Base64编解码 GitHub地址:https://github.com/BuYishi/cpp_base64_demo base64_demo.cpp #i ...

随机推荐

  1. Kd Tree算法详解

    kd树(k-dimensional树的简称),是一种分割k维数据空间的数据结构,主要应用于多维空间关键数据的近邻查找(Nearest Neighbor)和近似最近邻查找(Approximate Nea ...

  2. 使用for循环疑难问题

    接触js的基本语句之后,有一些疑难杂症在初期很难自己想出来,对我自己来说for输出三角形,倒三角行还有等腰三角形还是有点难度,所以记录一下,以便以后查找 倒三角,需要控制每行的输出个数,此处可以想象为 ...

  3. 自定义realm实现授权

    对用户和权限封装 更具用户查询已经拥有的角色 实现类 根据用户查询已经拥有的权限

  4. MIT6.828准备:MacOS下搭建xv6和risc-v环境

    本文介绍在MacOS下搭建Mit6.828/6.S081 fall2019实验环境的详细过程,包括riscv工具链.qemu和xv6,对于Linux系统同样可以参考. 介绍 只有了解底层原理才能写好上 ...

  5. [PHP学习教程 - 文件]002.修改上传文件大小限制(File Upload Limit)

    引言:通常大家直装xampp之后,默认的文件上传大小应该被设定成2M左右,这个时候如果上传超过2M的东西,就会报错,让人非常尴尬.如何修改呢? 导航索引: 概念 FTP常用API FTP封装类 其他 ...

  6. (一)DAO设计及BaseDAO和BookDAO的实现

    1.总体架构 MVC 设计模式:Model:POJO(Plain Old Java Object) Controller:ServletView:JSP + EL + JSTL 2.技术选型 数据库: ...

  7. MVC案例

    MVC案例分析: - 没有业务层,直接Servlet调用Dao,所以也没有业务操作.所有在DAO直接获取Connection对象 -采用MVCDs设计模式 -使用到的技术: mvc设计模式:JSP  ...

  8. 练习使用shell在阿里云安装MySQL

    #!/bin/bash #阿里云初始安装MySQL #step1:查寻MariaDB 并卸载 MariaDB_filename=`rpm -qa|grep mariadb` if [ -d " ...

  9. 前端Web浏览器基于H5如何实时播放监控视频画面(前言)之流程介绍

    先看上边这张图.由于离2020年12月各浏览器禁用Flash的日子越来越近,又正恰巧要做新录播项目,所以有了以下内容. 还记得去年也是这个时候,大约是四五六月份,甲方来了个需求想把车间的监控系统接入到 ...

  10. Spring AOP学习笔记01:AOP概述

    1. AOP概述 软件开发一直在寻求更加高效.更易维护甚至更易扩展的方式.为了提高开发效率,我们对开发使用的语言进行抽象,走过了从汇编时代到现在各种高级语言繁盛之时期:为了便于维护和扩展,我们对某些相 ...