背景

在一次调用三方API的时候,为了数据安全和三方API的请求和返回信息都用了rsa加密,由于rsa算法生成的内容是二进制的,所以需要用base64编码将二进制数据转化成64个可打印字符进行通信或者存储。在获取到三方的base64编码的返回信息后,解码碰到了各种问题,如下是日志里打印的三方的一个base64编码后的字符串

Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA

解码过程

1.使用标准库的base64.StdEncoding.DecodeString

最开始是印象标准库有一个base64.StdEncoding.DecodeString方法可以解码,就直接使用了这个方法

package mainimport("encoding/base64""fmt"
)func main(){encrypt := "Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA"_,err := base64.StdEncoding.DecodeString(encrypt)if err != nil {fmt.Println(err)}
}

执行结果

illegal base64 data at input byte 34
解码报错了,根据提示意思大概能猜到是第34位的字符‘_’ base64不认识,去查了下base64的索引表

发现base64的字符集内没有我们第34位对应的字符‘_’,当时想是不是做了类似urlencode的编码,防止http传输过程中部分字符转义,继续查base64文档发现了 如下一段内容

可以确定是将+和/分别改成了-和_, 那我们应该做一下字符串替换把-和_改回来就行,本来想直接在代码里面写字符串替换,后来想GO标准库还没细看,里面是不是还有现成的方法之前没发现,查了下标准库发现

URLEncoding和我们刚用的StdEncoding有一些区别,是用于URL和文件名,刚我们碰到的问题也是URL问题

2.用base64.URLEncoding.DecodeString方法尝试

经过了上一步的测试和文档查找,感觉用这个方法应该就可以搞定问题了,赶紧写个测试看看

package mainimport("encoding/base64""fmt"
)func main(){encrypt := "Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA"_,err := base64.URLEncoding.DecodeString(encrypt)if err != nil {fmt.Println(err)}
}

执行一下 又报错了,心累,看了下错误信息illegal base64 data at input byte 340,跟第一步报错的大致一样只是最后的位置变到了340,说明我们前面转义的问题用这个方法还是解决了,但是执行到最后的时候又有不标准字符了,继续查base64的文档,又有新发现,如图

大致意思是,如果编码的时候字节不足会在最后加一到两个=号,但看我们的字符串最后没有=,解码的时候解到最后又报错了,赶紧给字符串手动加个等号试试

package mainimport("encoding/base64""fmt"
)func main(){encrypt := "Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA"//为了不修改原字符串,没有直接在原字符串上追加encrypt = fmt.Sprint(encrypt,"==")_,err := base64.URLEncoding.DecodeString(encrypt)if err != nil {fmt.Println(err)}
}

加了两个等号,居然解码成功了,太不容易了,但是这问题也来了, 这追加的等号也不是固定的,如果在代码里面判断增加也很不方便啊,刚尝到查GO文档的好处了,带着问题找一个可以忽略最后等号的方法,看下GO文档里有没有,

3.使用base64.RawURLEncondig.DecodeString

前一个步骤我们得到的结论要在GO文档中找一个可以将-_还原成base64字符的同时可以让我们忽略末尾=号的,嗯  还真找到了一个base64.RawURLEncoding.DecodeString,赶紧试下

package mainimport("encoding/base64""fmt"
)func main(){encrypt := "Cf1WA2nBMo3H9G2UPhlLBBVBsMDl4udWr7__e6Iy93eIqLKi3EOjGhk8TkHujL1Uj6aGfZJNBzIbVE2NfNaz4pob8uiQvGaeTZdWP-8lFmAm6J1sz8N15xQkO7ADa5bNLCCqtlQbN2z7JcNenvFuID_rZGqb_1gmr-BGubGRMiMSK7RdjQYrMHaBcHLPB0UteakzcQwgKxCW7u0ECHqPJ39ne9JUG22JBWRo1ORuX5r30J_XrW3SQcdPSxfe0kvd61y12QOYh8VlOBBdBeDNnyDXefI_tDJDBFeqTXCgKu9wFkkWIZiM7WwqogaY-bvjUisbrPO4_fjJ1c0nWDOqRA"_,err := base64.RawURLEncoding.DecodeString(encrypt)if err != nil {fmt.Println(err)}
}

执行下,终于完美成功了。

总结

base64编码过程有两部特殊操作

  • url safe 将+/字符串转化成_-
  • no padding is add  末尾不增加=号

golang base64解码碰到的坑相关推荐

  1. Golang Base64编码解码

    Golang Base64编码解码 Golang内置支持Base64编码解码,Go的encoding/base64包遵照RFC 4648规范实现了base64编码解码功能,包括标准方式以及URL/文件 ...

  2. Base64解码过程必须关注的问题

    背景 这两天开发工作中,需要运用 Base64来进行数据的编解码.使用 Cryptopp库的 base64(网络上其他基于Boost 的 BIO)都会出现解码出来的字节数只是其中很少的一部分,具体编码 ...

  3. go-dongle 0.2.0 版本发布了,一个轻量级、语义化的 golang 编码解码、加密解密库

    dongle 是一个轻量级.语义化.对开发者友好的 Golang 编码解码和加密解密库 Dongle 已被 awesome-go 收录, 如果您觉得不错,请给个 star 吧 github.com/g ...

  4. base64 解码

    在ecplise上运行的好好的,但是到服务器上发现base64解码不正确,出现了乱码的现象 程序代码如下: new String(Base64.decode(infreturn.getReturnSt ...

  5. 做个游戏 writeup base64解码网址

    下载得到一个  jar  包,用  JD-GUI  打开 RGFqaURhbGlfSmlud2FuQ2hpamk=  -->  base64解码  -->  flag{DajiDali_J ...

  6. 说说初用 Mock 工具测试碰到的坑

    说说初用 Mock 工具测试碰到的坑 我是一个在校实习生,作为一个程序猿,是个菜鸟中战斗机!对于测试,只写过一点点简单到不能再简单了的 Junit 单元测试的例子(因为当时这足以应付学校课程的内容与要 ...

  7. //BASE64解码成File文件

    //BASE64解码成File文件public static void base64ToFile(String base64, String destPath,String fileName) {Fi ...

  8. php如何解码图片,php基于base64解码图片与加密图片还原实例_PHP

    本文实例讲述了php基于base64解码图片与加密图片还原的实现方法.分享给大家供大家参考.具体实现方法如下: 本例中$data是一段经过base64编码的图片.具体代码如下: 代码如下: //文件名 ...

  9. 学习使用Visual studio 时碰到的坑

    学习使用Visual studio 时碰到的坑 文章目录 学习使用Visual studio 时碰到的坑 异常1:OpenCV中出现"Microsoft C++ 异常: cv::Except ...

  10. des加密+base64编码,base64解码+des解密

    des加密+base64编码,base64解码+des解密 des简单介绍 base64简单介绍 运行效果图 TestActivity.java DataEncryptionUtil.java des ...

最新文章

  1. 我不喜欢Go语言的十个理由
  2. CentOS 6.9下OpenLDAP 的安装与配置
  3. The IP you're using to send email is not authorized
  4. matlab无刷双馈电机模型搭建,基于MATLAB的无刷双馈电机建模与仿真
  5. DBGridEh导出Excel等格式文件
  6. debian6 kvm安装虚拟机
  7. Linux系统调用getuid的简单分析
  8. DOTA 2血虐人类的OpenAI,原来靠的是作弊?
  9. 云市场合作伙伴-袋鼠云获A轮融资,成立一年半获三轮投资超亿元
  10. setContentView是如何把布局加上去的
  11. OpenGl图元基本操作之点选高亮
  12. 【C语言项目设计】趣味算术游戏设计
  13. 《现代信息检索导论》课程梳理
  14. 关闭Chrome启动时的360导航页面
  15. 项目进度管理__计划评审技术之标准正态分布表
  16. window系统中,交换键盘中win键和ctl键
  17. Win7 如何修改hosts文件
  18. python中for in的用法python中for in的用法
  19. Aforge做图像处理
  20. 欢乐庆团圆--记华清远见嵌入式学院老学员联谊会

热门文章

  1. 整合营销成功案例-卫龙辣条的逆袭路
  2. 数据库和 MIDP,第一部分:了解记录管理系统
  3. windows 10 连接android手机助手,Win10手机助手怎么用?win10手机助手使用方法
  4. DEJA_VU3D - Cesium功能集 之 007-军事标绘系列一:简单箭头
  5. Unity MVC实现背包系统(2)
  6. 恩尼格玛计划续章…以及,我们正在招贤纳士
  7. 操作系统的目标与作用
  8. vscode 文件夹中查找_VSCode 多文件搜索和替换
  9. php多域名跳转,旱的旱死,涝的涝死,中超联赛的怪事
  10. 软件设计师 如何准备考试(转载)