在收到客户端的数字签名signature后,需要对signature做base64的解码。代码如下所示:

 validate(SignedRequest) ->
RequestParts = string:split(SignedRequest, "."),%% 数字签名+'.'+algorithm, player_id等信息
Part1Original = lists:nth(1, RequestParts), Rem = byte_size(Part1Original) rem 4,
Suffix = case Rem of
2 -> "==";
3 -> "="
end,
Part1AppendSuffix = unicode:characters_to_binary([Part1Original, Suffix]), %% 填充'='
Part1Replaced1 = unicode:characters_to_binary(string:replace((Part1AppendSuffix), <<"-">>, <<"+">>, all), utf8), %% 替换'-'为'+'
Part1Replaced2 = unicode:characters_to_binary(string:replace(Part1Replaced1, <<"_">>, <<"/">>, all), utf8), %% 替换'_'为'/'
Signature = base64:decode(Part1Replaced2), DataHash = crypto:hmac(sha256, <<YOUR_APP_SECERT>>, lists:nth(2, RequestParts)),
case Signature =:= DataHash of
true -> success;
false -> failure
end.

向signature尾部追加'='的操作是Facebook官方示例中所没有的,Facebook示例在JavaScript的环境中测试时也是正常的,但是在erlang中调用base64:decode()时,若不做此追加处理,总是在最后的环节无法匹配前三个字节。无奈,根据报错提示找来base64.erl的对应代码,如下:

 decode([], A) -> A;
decode([$=,$=,C2,C1|Cs], A) ->
Bits2x6 = (b64d(C1) bsl 18) bor (b64d(C2) bsl 12),
Octet1 = Bits2x6 bsr 16,
decode(Cs, [Octet1|A]);
decode([$=,C3,C2,C1|Cs], A) ->
Bits3x6 = (b64d(C1) bsl 18) bor (b64d(C2) bsl 12)
bor (b64d(C3) bsl 6),
Octet1 = Bits3x6 bsr 16,
Octet2 = (Bits3x6 bsr 8) band 16#ff,
decode(Cs, [Octet1,Octet2|A]);
decode([C4,C3,C2,C1| Cs], A) ->
Bits4x6 = (b64d(C1) bsl 18) bor (b64d(C2) bsl 12)
bor (b64d(C3) bsl 6) bor b64d(C4),
Octet1 = Bits4x6 bsr 16,
Octet2 = (Bits4x6 bsr 8) band 16#ff,
Octet3 = Bits4x6 band 16#ff,
decode(Cs, [Octet1,Octet2,Octet3|A]).

可以看到,它只匹配4种情形,而报错时剩余前3个字节无法匹配(注意是逆序处理的),可以推定被解码的字节数不足。这里一篇博客对Base64有很清晰的讲解:

http://www.ruanyifeng.com/blog/2008/06/base64.html

在加密前,字节数组是每3个字节为一组被编码为4个字节的。当剩余字节数不足3时,有剩余1个字节和2个字节两种情形,前者被编码为2个字节,需要向尾部追加"==",后者被编码为3个字节,需要向尾部追加"="。而erlang这里报错时,我统计了签名的字节数,是不能被4整除的。因此先判断字节数,并据字节数追加相应的'=',并测试成功。

使用JavaScript的库crypto-js测试时没有出现此问题,猜想其内部可能根据字节数做了追加处理,具体就不再深究了。

erlang的base64解码问题的更多相关文章

  1. C# Base64解码 二进制输出

    具体的:Base64编码解码还需要学习 /// <summary> /// base64 解码Excel下载 /// </summary> /// <param name ...

  2. 微信小程序之图片base64解码

    不知道大家在做微信小程序的时候遇到base64解码的问题,我之前在做微信小程序的时候遇到base64解析图片一直有问题,所以在这里把遇到的问题和解决方案在这里记录一下: 在平时的项目中我们是直接用ba ...

  3. 将图片文件转化为字节数组字符串,并对其进行Base64编码处理,以及对字节数组字符串进行Base64解码并生成图片

    实际开发中涉及图片上传并且量比较大的时候一般处理方式有三种 1.直接保存到项目中 最老土直接方法,也是最不适用的方法,量大对后期部署很不方便 2.直接保存到指定路径的服务器上.需要时候在获取,这种方式 ...

  4. SqlServer Base64解码中文

    最近在做一个和拥有TurboCRM相关的项目,其中需要取出客户信息的联系人字段,经过查看,这个字段在存入时用Base64加密过了 这个功能在应用层实现是很方便的,但是由于一些特殊原因,只能放到SqlS ...

  5. python3 base64解码出现TypeError:Incorrect padding

    今天在解决爬虫对加密参数的分析时,需要使用到base64解码.但是过程中出现了TypeError:Incorrect padding的错误提示.以下是解决方法,以便查阅. 其实正常使用base64是不 ...

  6. 【java工具类】对字节数组字符串进行Base64解码并生成图片

    import java.io.File;import java.io.FileOutputStream;import java.io.OutputStream;import org.springfra ...

  7. base64解码

    网络传输经常用base64编码的数据,因此我们需要将其解码成正常字符集合. base64.h #ifdef __cplusplus extern "C" { #endif char ...

  8. bootstrap-wysiwyg 结合 base64 解码 .net bbs 图片操作类 (二) 图片裁剪

    图片裁剪参见: http://deepliquid.com/projects/Jcrop/demos.php?demo=thumbnail        一个js插件 http://www.mikes ...

  9. bootstrap-wysiwyg 结合 base64 解码 .net bbs 图片操作类

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Dr ...

随机推荐

  1. Tengine的concat模块与js、css合并

    首先,先走出一个误区 ,下面是tengine-cn邮件列表里的一篇邮件原文:“看了这个例子就了解了,这个所谓的合并请求只是把所有的CSS或JAVASCRIPT请求合并,必须是同一个文件类型的.我开始想 ...

  2. ActivityGroup中监听返回按键

    如果你想使用ActivityGroup来统一管理Activity的话,当然首先这是一种很好的方法,但是如果你想在ActivityGroup里面拦截返回按键来进行统一管理的话,直接覆写onKeyDown ...

  3. electron 编译成exe

    前提:现在有一个electron项目,等待打包成exe. 一,运行”electron .“,看运行是否正常.不正常则继续调试,正常可进入到第二步. 二,运行“electron-packager . m ...

  4. Centos7安装遇到的问题及详解

    1.虚拟机中选择的是NAT模式,我的笔记本电脑是拨号上网,用桥接模式,找不到网卡,在windows的dos界面用ipconfig查看的结果 PPP适配器 宽带连接:IPv4 地址 . . . . . ...

  5. hadoop学习 的yarn

    Yarn的产生 mapReduc1.0 1单点故障 2扩展效率低 3资源利用率高 降低运维成本 方便数据共享 多计算框架支持 MapReduce Spark Storm Yarn的架构图 Yarn模块 ...

  6. JS --- 数组循环要用length

    socket.on("receive", function (data) { deviceone.print("返回的数据:"+data) // 发送异常 va ...

  7. Go --- GC优化经验

    不想看长篇大论的,这里先给个结论,go的gc还不完善但也不算不靠谱,关键看怎么用,尽量不要创建大量对象,也尽量不要频繁创建对象,这个道理其实在所有带gc的编程语言也都通用. 想知道如何提前预防和解决问 ...

  8. 学习日记之抽象工厂模式和Effective C++

    抽象工厂模式(Abstract Factory):提供一个创建一系列相关或者相互依赖对象的接口.而无需制定他们详细的类. (1),工厂方法模式是定义一个用于创建对象的接口.让子类决定实例化哪一个类. ...

  9. spring-quartz定时任务使用小结

    在实际项目中,通常须要用到定时任务(定时作业).spring框架提供了非常好的实现. 1.  下载spring-quartz插件包 这里默认当前系统中是集成了spring框架的基本功能的.去网上下载s ...

  10. es删除文档或者删除索引

    es删除文档或者删除索引 学习了:https://www.imooc.com/video/15771 删除文档: DELETE http://127.0.0.1:9200/people/man/1 删 ...