erlang大坑——加密和字符串处理
2016-03-22 21:56
459 查看
1、问题描述
因业务要求,需要对指定的http请求内容进行RSA签名,并且将签名结果和请求内容用json格式打包。这里包括两个需要处理的点:1、用RSA私钥签名;2、把http请求json化。2、处理签名
目前项目使用的erlang版本是17.0,这个版本有专门针对RSA的库即public_key,但是查看public_key相关描述sign(Msg, DigestType, Key) -> binary() Types: Msg = binary() | {digest,binary()} The msg is either the binary "plain text" data to be signed or it is the hashed value of "plain text" i.e. the digest. DigestType = rsa_digest_type() | dss_digest_type() | ecdsa_digest_type() Key = rsa_private_key() | dsa_private_key() | ec_private_key() Creates a digital signature.
明显,参数需要rsa_private_key()类型参数,参数定义
-record('RSAPrivateKey',{ version, modulus, publicExponent, privateExponent, prime1, prime2, exponent1, exponent2, coefficient, otherPrimeInfos = asn1_NOVALUE}).对于只有privatekey而没有生成key的两个素数的应用场景来说,这个库就是渣,感觉并没有什么卵用。其他方案?java和c++应该是有对应的库的,erlang中也存在调用java和c++库的方法,两种方案区别如下:
1、java。erlang中有jinterface用来调用java,对于erlang来说,jinterface类似于启动一个新的节点,erlang连接该节点之后可以向该节点发送和接受消息,以此来请求RSA签名和接受签名结果。优点:可以使用庞大的java库。缺点:慢,毕竟需要跨节点通信;麻烦,新增一个节点,特别对于分布式环境,还要防止节点之间自动连接等等。
2、c++。erlang中有nif机制对应调用C++,C++方法可以单独运行在一个节点,也可以和erlang在同一个节点,但是一般不会单独分开一个节点,因为单独在一个节点会遇到和jinterface一样的困难——慢,麻烦。优点:快,顺序运算速度是erlang的7倍。缺点:不安全,发生异常会直接导致节点挂掉,并且没有任何征兆。
综上,结合应用场景,由于不需要大量请求签名,使用方案1虽然比较慢应该也不会卡住主流程,并且解密方是使用java解密,用java可以省去很多编码之类的问题。jinterface使用流程参考http://erlang.org/doc/apps/jinterface/jinterface_users_guide.html,以下为java代码
OtpNode node = new OtpNode("g35_java@127.0.0.1", "g35_java"); //启动节点 OtpMbox mbox = node.createMbox(); //创建消息队列 mbox.registerName("java"); //注册名称 int flag = 1; while (flag == 1) { try { OtpErlangObject o; OtpErlangTuple msg; OtpErlangPid from; o = mbox.receive(); //收取请求 if (o instanceof OtpErlangTuple) { msg = (OtpErlangTuple)o; from = (OtpErlangPid)(msg.elementAt(0)); // //字符片段1 OtpErlangString content = (OtpErlangString)msg.elementAt(1); String contentString = convertErlangString(content); //字符串转换 String sign = RSASignature.sign(signString); //数字签名 OtpErlangObject returnSign = new OtpErlangString(sign); //返回结果 mbox.send(from, returnSign); }需要注意的是,erlang的String在java中是OtpErlangString,这个结构直接使用是错误的,需要经过转换。
3、erlang转换json
erlang转换成json已经有很强大的库,例如mochijson之类,然而对于字符串处理能力奇差的erlang来说,转换json还是存在很多坑。例如(db_20001_1@127.0.0.1)9> io:format("~ts", [common_json2:to_json([{name, "123"}, {age, 24}])]). {"name":"123","age":24}ok看起来是符合json规范的,但是如果用这个字符串进行网络传输就不行了,原因如下
(db_20001_1@127.0.0.1)11> io:format("~w", [common_json2:to_json([{name, "123"}, {age, 24}])]). [123,[34,[110,97,109,101],34],58,[34,<<49,50,51>>,34],44,[34,[97,103,101],34],58,[50,52],125]ok即实际得出的json串是各种类型的erlang数据拼凑起来的,实际可以用于传输的应该是
(db_20001_1@127.0.0.1)12> [123,34,110,97,109,101,34,58,34,49,50,51,34,44,34,97,103,101,34,58,50,52,125]. "{\"name\":\"123\",\"age\":24}"这里需要做的操作就是
F = fun(Element) -> case is_binary(Element) of true -> binary_to_list(Element); false -> Element end end, Param3 = lists:map(F, lists:flatten(Param22)), Param4 = lists:flatten(Param3),特别的,如果有中文字符串,那需要处理的更复杂一点,例如
(db_20001_1@127.0.0.1)15> common_json2:to_json([{name, "你妹子"}, {age, 24}]). ** exception error: bad argument in function list_to_binary/1 called as list_to_binary([20320,22969,23376]) in call from common_json2:prepare_for_json/1 (e:/G35Server/src/common/common_json2.erl, line 32) in call from common_json2:proplist_to_json/2 (e:/G35Server/src/common/common_json2.erl, line 52) in call from common_json2:list_to_json/2 (e:/G35Server/src/common/common_json2.erl, line 46) in call from common_json2:to_json/1 (e:/G35Server/src/common/common_json2.erl, line 16) (db_20001_1@127.0.0.1)16> io:format("~w", [common_json2:to_json([{name, xmerl_ucs:to_utf8("你妹子")}, {age, 24}])]). [123,[34,[110,97,109,101],34],58,[34,[92,117,52,102,54,48],[92,117,53,57,98,57],[92,117,53,98,53,48],34],44,[34,[97,103,101],34],58,[50,52],125]ok如上,直接使用中文字符串会异常,必须转换成utf-8。关于json传输,查看http://whathellk.lofter.com/post/1cc5e53b_4481518
4、总结
1、适当使用jinterface和nif等工具来拓展erlang功能;2、字符串操作不光是要查看内容,更要查看字符串原始list,选择合适类型的字符串(io:format("~w", [String])查看原始list)。
相关文章推荐
- OpenSSL编程之RSA
- 每 172 个活动 RSA 证书中就有一个容易受到攻击
- XML 与 JSON 优劣对比
- VBA将excel数据表生成JSON文件
- 用ASP编写的加密和解密类
- Erlang项目内存泄漏分析方法
- Erlang实现的一个Web服务器代码实例
- Erlang并发编程介绍
- Erlang的一些编程技巧分享
- newtonsoft.json解析天气数据出错解决方法
- VBS脚本加密/解密VBS脚本(简易免杀版1.1)
- BAT加密工具 EncryBat 非编译型bat批处理加密方案与代码
- C#对称加密(AES加密)每次生成的结果都不同的实现思路和代码实例
- SQLServer 2008中的代码安全(一) 存储过程加密与安全上下文
- 实例讲解SQL Server加密功能
- C#实现对文件进行加密解密的方法
- C#实现数据包加密与解密实例详解
- vbs 解析json jsonp的方法
- C#最简单的字符串加密解密方法
- C#加密app.config中连接字符串的方法