㈠ 如何使用 Oauth 实现一个安全的 REST API 服务
场景
想要为开发工程师们开发一个既能满足REST约束条件和原则又不像OAuth OAuth 那样复杂 the complexity ,仅仅使用简单的传值语句或者其它简单但同样安全的方法就能实现的web API?
聪明人会有聪明的想法…
问题
直接通过HTTP literally passing the credentials over HTTP以文本方式传输鉴权信息可能会被破译; 尤其在 Gawker incident, 再以文本或是弱加密的方式传输鉴权信息是非常不安全的做法 weakly-hashed anything is usually a bad idea.
即便是使用哈希加密后还是很有可能被人根据彩虹表 Rainbow Table破译出与用户名匹配的密码(个别案例)
这可该怎么办,真是郁闷…
也许你又会想到很多公共的API popular public APIs在请求中采用双数据的模式:一个公有值一个(最好是有)只有属主能访问的私有值。
”还是有点不对!”这不跟原来(用户名密码模式)文本模式差不多么,还是可能会被(嗅探器)破译。
这时候你可能准备放弃并采用OAuth模式了,但仍坚信必有某种简单方法能实现公用webAPI安全访问私有鉴权信息。
解决方案
连续2天的Peyote实验后(你可能会找到更好的放松办法),结论终于呈现在你眼前:Amazon是拥有最大的、使用最多的在线网络API的网络服务之一,并且根本不支持OAuth!
经过一个下午长时间的狂想之后,你最终败下阵来,并看到Amazon是如何保持API请求安全的。你不清楚为什么,但读完整页关于如何为Amazon网络服务装配一个请求后,你依然觉得不完全合理。这个“签名”和什么连在一起?代码示例中的“data”参数是什么?这样,你会继续查找关于“安全API设计”的文章。。。
当遇到其他人问同样的问题时,你看到一些指出"HMAC"或其他事物的优秀回复,但还是不太确定。
你找到其他鼓励你使用“HMAC”的文章并且你正H-FINE地使用它,如果有人将“HMAC”解释成简明的H_ENGLISH的话。
你的确偶遇了一个有道理的蒸馏的基本概念,它是这样一简明的英语描述的:
一个服务器和客户端知道一个公钥和一个私钥;只有服务器和客户端知道私钥,但每个人都知道公钥。。。但不关心别人所知道的。
一个客户端生成一个唯一的HMAC(哈希)表示它到服务器的请求。通过把请求数据(参数和值或XML/JSON或任何它计划发送的数据)以及请求数据的散列blob和私钥结合来实现。
客户端随后将这个HASH以及所有它将要发送的参数和值一并发给服务器。
服务器接到请求,并使用与客户端相同的方式重新生成自己独有的基于提交值的HMAC(哈希)。
然后,服务器比较这两个HMAC,如果相同,服务器就信任这个客户端并执行请求。
这似乎很直截了当。最初让你困惑的是,你以为原始请求是经过加密传送的,但实际上,HMAC方法所做的一切只是使用只有客户端和服务器才知道的私钥将参数生成为一些独特的校验和(哈希)。
随后,客户端将这个校验和及原始参数和值发给服务器,然后服务器复核校验和(哈希)以确定它接受客户端所发的请求。
因为根据假设,只有在客户端和服务器知道私钥,我们假设如果他们的哈希匹配,那么它们会互相信任,以至服务器随即正常处理这个请求。
你知道在现实中,这就相当于某人过来对你说:“Jimmy让我告诉你把钱给Johnny”,但你不知道这个人是谁,所以你要伸出手去试探他,看看他是否知道这个秘密握手。
如果三次握手证明无误,则通讯继续进行,否则中断通讯。.
你明白了大概是怎么回事,但还是想会不会还有更好的方法呢?还好,有tarsnap网站 tarsnap帮你答疑解惑。看看亚马逊是如何解决签名认证问题的Amazon screwed this up with Signature Version 1.
看完了亚马逊的web service是如何鉴权的,re-read how Amazon Web Services does authentication 讲的确实有道理,整个流程如下:
[客户端]在调用REST API之前,首先将待发送消息体打包, combine a bunch of unique data together(websevice端将要接收的数据)
[客户端]用系统分派的密钥使用哈希(最好是HMAC-SHA1 or SHA256 ) 加密(第一步的数据).
[客户端]向服务器发送数据:
用户身份认证信息例如,用户ID,客户ID或是其他能别用户身份的信息。这是公共API,大家都能访问的到(自然也包括了那些居心叵测的访问者)系统仅仅需要这部分信息来区分发信人而不考虑可靠与否(当然可以通过HMAC来判断可靠性).
发送生成的HMAC码.
发送消息体(属性名和属性值),如果是私有信息需要加密,像是(“mode=start&number=4&order=desc”或其他不重要的信息)直接发送即可.
(可选项)避免重放攻击 “replay attacks” o的唯一办法就是加上时间戳。在使用HMAC算法时加入时间戳,这样系统就能依据一定的条件去验证是否有重放的请求并拒绝.
[服务器端]接收客户端发来的消息.
[服务器端] (参看可选项)检查接收时间和发送时间的间隔是否在允许范围内(5-15分)以避免重放攻击replay attacks.
提示: 确保待检对象的时区无误daylight savings time
更新: 最近得到的结论就是直接使用UTC时区而无需考虑DST的问题 use UTC time .
[服务器端]使用发送请求中用户信息(比如.API值)从数据库检索出对应的私匙.
[服务器端] 跟客户端相同,先将消息体打包然后用刚得到的私匙加密(生成HMAC)消息体.
(参看可选项) 如果你使用了加入时间戳的方式避免重放攻击,请确保服务端生成的加密信息中拥有和客户端相同的时间戳信息以避免中间人攻击man-in-the-middle attack.
[服务器端] 就像在客户端一样,使用HMAC哈希加密刚才的信息体.
[服务器端] 将服务器端刚生成的哈希与客户端的对比。如果一致,则通讯继续;否则,拒绝请求!
提示: 在打包消息体的时候一定要考虑清楚,如果像亚马逊进行签名版本1中信息识别那样会面临哈希冲突的问题 open yourself up to hash-collisions! (建议:将整个包含URL的请求加密即可!)
特别提示:私匙绝对不能在通讯过程中传递,它仅仅用来生成HMAC,服务器端会自动查询出它的私匙并重新生成自己的HMAC.我来翻译公匙仅仅用来区分不同的用户,即使被破解也无所谓。因为此时的消息无需判断其可靠性,服务端和客户端还是要通过私匙来加密(比如,前缀、后缀,倍数等等)
10/13/11更新:Chris最近发现 pointed out 如果在HMAC计算中加入了URI或是HTTP请求/回复,攻击者更易通过更改末端或是HTTP方法来搞破坏。比如,在HTTP POST方法中将/issue/create改成/user/delete。
㈡ 如何使用 Oauth 实现一个安全的 REST API 服务
看完了亚马逊的web service是如何鉴权的,re-read how Amazon Web Services does authentication 讲的确实有道理,整个流程如下:
[客户端]在调用REST API之前,首先将待发送消息体打包, combine a bunch of unique data together(websevice端将要接收的数据)
[客户端]用系统分派的密钥使用哈希(最好是HMAC-SHA1 or SHA256 ) 加密(第一步的数据).
[客户端]向服务器发送数据:
用户身份认证信息例如,用户ID,客户ID或是其他能别用户身份的信息。这是公共API,大家都能访问的到(自然也包括了那些居心叵测的访问者)系统仅仅需要这部分信息来区分发信人而不考虑可靠与否(当然可以通过HMAC来判断可靠性).
发送生成的HMAC码.
发送消息体(属性名和属性值),如果是私有信息需要加密,像是(“mode=start&number=4&order=desc”或其他不重要的信息)直接发送即可.
(可选项)避免重放攻击 “replay attacks” o的唯一办法就是加上时间戳。在使用HMAC算法时加入时间戳,这样系统就能依据一定的条件去验证是否有重放的请求并拒绝.
[服务器端]接收客户端发来的消息.
[服务器端] (参看可选项)检查接收时间和发送时间的间隔是否在允许范围内(5-15分)以避免重放攻击replay attacks.
提示: 确保待检对象的时区无误daylight savings time
更新: 最近得到的结论就是直接使用UTC时区而无需考虑DST的问题 use UTC time .
[服务器端]使用发送请求中用户信息(比如.API值)从数据库检索出对应的私匙.
[服务器端]
跟客户端相同,先将消息体打包然后用刚得到的私匙加密(生成HMAC)消息体.
(参看可选项) 如果你使用了加入时间戳的方式避免重放攻击,请确保服务端生成的加密信息中拥有和客户端相同的时间戳信息以避免中间人攻击man-in-the-middle attack.
[服务器端] 就像在客户端一样,使用HMAC哈希加密刚才的信息体.
[服务器端]
将服务器端刚生成的哈希与客户端的对比。如果一致,则通讯继续;否则,拒绝请求!
提示: 在打包消息体的时候一定要考虑清楚,如果像亚马逊进行签名版本1中信息识别那样会面临哈希冲突的问题 open yourself up to hash-collisions! (建议:将整个包含URL的请求加密即可!)
特别提示:私匙绝对不能在通讯过程中传递,它仅仅用来生成HMAC,服务器端会自动查询出它的私匙并重新生成自己的HMAC.我来翻译公匙仅仅用来区分不同的用户,即使被破解也无所谓。因为此时的消息无需判断其可靠性,服务端和客户端还是要通过私匙来加密(比如,前缀、后缀,倍数等等)
10/13/11更新:Chris最近发现 pointed out 如果在HMAC计算中加入了URI或是HTTP请求/回复,攻击者更易通过更改末端或是HTTP方法来搞破坏。比如,在HTTP POST方法中将/issue/create改成/user/delete。多谢Chris的提醒!
㈢ java rest api接口 怎么保证安全性
尝试这样加密:
客户端:
1、设置一个key(和服务器端相同)
2、根据上述key对请求进行某种加密(加密必须是可逆的,以便服务器端解密)
3、发送请求给服务器
服务器端:
1、设置一个key
2、根据上述的key对请求进行解密(校验成功就是“信任”的客户端发来的数据,否则拒绝响应)
3、处理业务逻辑并产生结果
4、将结果反馈给客户端
㈣ 这是什么加密方式
7种html加密方式介绍2009-11-26 12:35一:最简单的加密解密
二:转义字符""的妙用
三:使用Microsoft出品的脚本编码器Script Encoder来进行编码 (自创简单解码)
四:任意添加NUL空字符(十六进制00H) (自创)
五:无用内容混乱以及换行空格TAB大法
六:自写解密函数法
七:错误的利用 (自创) 在做网页时(其实是网页木马呵呵),最让人烦恼的是自己辛辛苦苦写出来的客户端IE运行的JAVASCRIPT代码常常被别人轻易的拷贝,实在让自己的心里有点不是滋味,要知道自己写点东西也挺累的......^*^
但我们也应该清楚地认识到因为JAVASCRIPT代码是在IE中解释执行,要想绝对的保密是不可能的,我们要做的就是尽可能的增大拷贝者复制的难度,让他知难而退(但愿~!~),下面我结合自己这几年来的实践,及个人研究的心得,和大家一起来探讨一下网页中JAVASCRIPT代码的加密解密技术。
以加密下面的JAVASCRIPT代码为例:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
alert("黑客防线");
</SCRIPT>一:最简单的加密解密
大家对于JAVASCRIPT函数escape()和unescape()想必是比较了解啦(很多网页加密在用它们),分别是编码和解码字符串,比如例子代码用escape()函数加密后变为如下格式:
以下是代码片段:
alert%28%22%u9ED1%u5BA2%u9632%u7EBF%22%29%3B
如何?还看的懂吗?当然其中的ASCII字符"alert"并没有被加密,如果愿意我们可以写点JAVASCRIPT代码重新把它加密如下:
以下是代码片段:
%61%6C%65%72%74%28%22%u9ED1%u5BA2%u9632%u7EBF%22%29%3B呵呵!如何?这次是完全都加密了!
当然,这样加密后的代码是不能直接运行的,幸好还有eval(codeString)可用,这个函数的作用就是检查JavaScript代码并执行,必选项 codeString 参数是包含有效 JavaScript 代码的字符串值,加上上面的解码unescape(),加密后的结果如下:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
var code=unescape("%61%6C%65%72%74%28%22%u9ED1%u5BA2%u9632%u7EBF%22%29%3B");
eval(code)
</SCRIPT>
是不是很简单?不要高兴,解密也就同样的简单,解密代码都摆给别人啦(unescape())!呵呵
二:转义字符""的妙用
大家可能对转义字符""不太熟悉,但对于JavaScript提供了一些特殊字符如:n (换行)、 r (回车)、' (单引号 )等应该是有所了解的吧?其实""后面还可以跟八进制或十六进制的数字,如字符"a"则可以表示为:"141"或"x61"(注意是小写字符"x"),至于双字节字符如汉字"黑"则仅能用十六进制表示为"u9ED1"(注意是小写字符"u"),其中字符"u"表示是双字节字符,根据这个原理例子代码则可以表示为:
八进制转义字符串如下:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
eval("")
</SCRIPT>十六进制转义字符串如下:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
eval("")
</SCRIPT>这次没有了解码函数,因为JavaScript执行时会自行转换,同样解码也是很简单如下:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
alert("")
</SCRIPT>
就会弹出对话框告诉你解密后的结果!
三:使用Microsoft出品的脚本编码器Script Encoder来进行编码
工具的使用就不多介绍啦!我是直接使用JavaScript调用控件Scripting.Encoder完成的编码!代码如下:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
var Senc=new ActiveXObject("Scripting.Encoder");
var code='<SCRIPT LANGUAGE="JavaScript">rnalert("黑客防线");rn</SCRIPT>';
var Encode=Senc.EncodeScriptFile(".htm",code,0,"");
alert(Encode);
</SCRIPT>编码后的结果如下:
以下是代码片段:
<SCRIPT LANGUAGE="JScript.Encode">#@~^FgAAAA==@#@&ls DD`J黑客防线r#p@#@&FgMAAA==^#~@</SCRIPT>够难看懂得吧?但相应的解密工具早已出来,而且连解密网页都有!因为其解密网页代码过多,我就不多说拉!给大家介绍一下我独创的解密代码,如下:
以下是代码片段:
<SCRIPT LANGUAGE="JScript.Encode">
function decode()
alert(decode.toString());
</SCRIPT>咋样?够简单吧?它是原理是:编码后的代码运行前IE会先对其进行解码,如果我们先把加密的代码放入一个自定义函数如上面的decode()中,然后对自定义函数decode调用toString()方法,得到的将是解码后的代码!
如果你觉得这样编码得到的代码LANGUAGE属性是JScript.Encode,很容易让人识破,那么还有一个几乎不为人知的window对象的方法execScript(),其原形为:
window.execScript( sExpression, sLanguage )
参数:
sExpression: 必选项。字符串(String)。要被执行的代码。
sLanguage: 必选项。字符串(String)。指定执行的代码的语言。默认值为 Microsoft JScript
使用时,前面的"window"可以省略不写!
利用它我们可以很好的运行编码后的JavaScript代码,如下:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
execScript("#@~^FgAAAA==@#@&ls DD`J黑客防线r#p@#@&FgMAAA==^#~@","JScript.Encode")
</SCRIPT>
你可以利用方法二对其中的""号内的字符串再进行编码,使得"JScript.Encode"以及编码特征码"#@~^"不出现,效果会更好!
四:任意添加NUL空字符(十六进制00H)
一次偶然的实验,使我发现在HTML网页中任意位置添加任意个数的"空字符",IE照样会正常显示其中的内容,并正常执行其中的JavaScript 代码,而添加的"空字符"我们在用一般的编辑器查看时,会显示形如空格或黑块,使得原码很难看懂,如用记事本查看则"空字符"会变成"空格",利用这个原理加密结果如下:(其中显示的"空格"代表"空字符")
以下是代码片段:
<S C RI P T L ANG U A G E =" J a v a S c r i p t ">
a l er t (" 黑 客 防 线") ;
< / SC R I P T>
如何?是不是显得乱七八糟的?如果不知道方法的人很难想到要去掉里面的"空字符"(00H)的!
五:无用内容混乱以及换行空格TAB大法
在JAVASCRIPT代码中我们可以加入大量的无用字符串或数字,以及无用代码和注释内容等等,使真正的有用代码埋没在其中,并把有用的代码中能加入换行、空格、TAB的地方加入大量换行、空格、TAB,并可以把正常的字符串用""来进行换行,这样就会使得代码难以看懂!如我加密后的形式如下:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
"xajgxsadffgds";1234567890
625623216;var $=0;alert//@$%%&*()(&(^%^
//cctv function//
(//hhsaasajx xc
/*
asjgdsgu*/
"黑客防线"//ashjgfgf
/*
@#%$^&%$96667r45fggbhytjty
*/
//window
)
;"#@$#%@#432hu";212351436
</SCRIPT>
至少如果我看到这样的代码是不会有心思去分析它的,你哪?
六:自写解密函数法
这个方法和一、二差不多,只不过是自己写个函数对代码进行解密,很多VBS病毒使用这种方法对自身进行加密,来防止特征码扫描!下面是我写的一个简单的加密解密函数,
加密代码如下(详细参照文件"加密.htm"):
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
function compile(code)
{
var c=String.fromCharCode(code.charCodeAt(0)+code.length);
for(var i=1;i<code.length;i++){
c+=String.fromCharCode(code.charCodeAt(i)+code.charCodeAt(i-1));
}
alert(escape(c));
}
compile('alert("黑客防线");')
</SCRIPT>运行得到加密结果为:o%CD%D1%D7%E6%9CJ%u9EF3%uFA73%uF1D4%u14F1%u7EE1Kd
相应的加密后解密的代码如下:
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
function uncompile(code)
{
code=unescape(code);
var c=String.fromCharCode(code.charCodeAt(0)-code.length);
for(var i=1;i<code.length;i++){
c+=String.fromCharCode(code.charCodeAt(i)-c.charCodeAt(i-1));
}
return c;
}
eval(uncompile("o%CD%D1%D7%E6%9CJ%u9EF3%uFA73%uF1D4%u14F1%u7EE1Kd"));
</SCRIPT>
七:错误的利用
利用try{}catch(e){}结构对代码进行测试解密,虽然这个想法很好(呵呵,夸夸自己),因为实用性不大,我仅给个例子
以下是代码片段:
<SCRIPT LANGUAGE="JavaScript">
var a='alert("黑客防线");';
var c="";
for(var i=0;i<a.length;i++){
c+=String.fromCharCode(a.charCodeAt(i)^61);}
alert(c);//上面的是加密代码,当然如果真正使用这个方法时,不会把加密写上的
//现在变量c就是加密后的代码
//下面的函数t()先假设初始密码为0,解密执行,
//遇到错误则把密码加1,然后接着解密执行,直到正确运行
以下是代码片段:
var d=c; //保存加密后的代码
var b=0; //假定初始密码为0
t();
function t()catch(e){
c="";
for(var i=0;i<d.length;i++){
c+=String.fromCharCode(d.charCodeAt(i)^b);}
b+=1;
t();
//setTimeout("t()",0);
}
}
</SCRIPT>
㈤ java开发 Rest 接口怎样设计api_key 也就是我的api怎样才能不被自由访问,需要在header加入验证
以下仅供参考:
如果rest端要自己维护api_key,类似存储在数据库里,就分发(授权)给客户端某个api_key,然后客户端用api_key和一些其他条件如时间戳+签名去rest端换取一个token,最后客户端用这个token和rest端进行交互,可以参考下微信的oauth鉴权.
如果rest端不维护api_key,也就省去分发(授权)客户端api_key的工作,此时客户端用传递的参数和其他条件如时间戳+签名去rest端换取一个token..同上
上述所说的token都是唯一的,对于同一个客户端的请求而言,下次刷取token的时候,之前产生的token作废;
token本身应该要维持在rest端,也应该有一个过期的限制;
(参数)+(api_key)+时间戳 通过加密算法(如sha2)生成签名,rest端同逻辑校验签名是否合法一般就能卡掉一大部分的访问,
至于api_key或者token放在哪里,一般无状态访问比较常见是在head里(常见如angularjs项目),这里我觉得随意,因为只要被拦截都可见,只是head可以放比较多的东西用来障目就是了.
当然,如果正在用的token被拦截,同样也是可以随意访问的,因此可能要求https协议加证书应该会更牢固点(没试过);
一般就这样,再高的我也不懂了,如果陈述有什么问题,者有什么看法,也还请不吝赐教~
㈥ 如何在 Swift 中使用 CommonCrypto 类进行加密
现在,许多开发者已经不需要在 App 中进行加密处理。即使你在远程服务器上使用了 REST API,通常情况下使用 HTTPS
就可以解决大多数的安全通信问题,剩下的问题可以使用苹果提供的“保护模式”和硬件/软件加密组合方式来解决。然而在很多情况下,你还是需要对通信或文件进行加密。也许你正在把一个现有的涉及到文件/信息加密的方案移植到
iOS 上,也许你在制作一个保密性要求极高的App,或者你只是想提高数据的安全级别(这是一件好事)。
无论是哪种情况,(在iOS和OS
X系统中)Cocoa 都选择 CommonCrypto 来完成任务。然而 CommonCrypto 的 API
使用的仍然是老旧的C风格(C-Style)。这种 API 已经过时了,在 Swift 中用它们非常别扭。此外,在 Swift 中用强类型属性处理
CCCrypt 中不同类型的数据(对称式加密框架的主要加密/解密功能)很不优雅。我们先来看一下 CCCrypt 的定义:
CCCrypt(op: CCOperation, alg: CCAlgorithm, options: CCOptions, key:
UnsafePointer<Void>, keyLength: Int, iv:
UnsafePointer<Void>, dataIn: UnsafePointer<Void>,
dataInLength: Int, dataOut: UnsafeMutablePointer<Void>,
dataOutAvailable: Int, dataOutMoved: UnsafeMutablePointer<Int>)
再来看看 Objective-C(更准确来说是 C 版本的)函数声明:
CCCryptorStatus
CCCrypt( CCOperation op, // operation: kCCEncrypt or kCCDecrypt
CCAlgorithm alg, // algorithm: kCCAlgorithmAES128... CCOptions
options, // operation: kCCOptionPKCS7Padding... const void *key,
// key size_t keyLength, // key length const void *iv,
// initialization vector (optional) const void *dataIn, //
input data size_t dataInLength, // input data length void *dataOut,
// output data buffer size_t dataOutAvailable, // output data
length available size_t *dataOutMoved) // real output data length
generated
在 Objective-C 中,可以简单地使用预定义常量(比如“kCCAlgorithm3DES”)来定义这些参数,然后传入不同的数组和大小,完全不必担心它们的确切类型(给 size_t 参数传入 int 变量,或者给 void 参数传入 char 变量)。这不是最好的做法,但确实可以完成任务(只需要进行一些类型转换)。
但是 Swift 剔除了 Objective-C 中属于 C 的部分,因此我们需要做一些准备工作才能在 Swift 和 Cocoa 中使用 CommonCrypto。
操作(Operation)、算法(Algorithm)和设置(Options)
在
App
中对称编码是最简单的一种发送和接收加密数据的方法。这种方法只有一个密钥,它用于加密和解密操作(非对称加密则不同,它通常使用一对公-私密钥)。对称密码有许多不同的算法,所有的算法都可以有不同的设置。三个主要概念是:操作(加密/解密)、算法(DES,AES,RC4……)和设置,对应
CommonCrypto 的 CCOperation、CCAgorithm 和 CCOptions。
CCOperation、CCAgorithm 和 CCOptions 本质上就是 uint32_t(一个占32位存储的 unsigned int),所以我们可以通过 CommonCrypto 常量来构造它们:
let operation = CCOperation(kCCEncrypt)let algorithm =
CCAlgorithm(kCCAlgorithmAES)let options =
CCOptions(kCCOptionPKCS7Padding | kCCOptionECBMode) Unsafe 指针
Swift
抽象出 Unsafe 指针来对应 C 语言的指针(C-Pointers)。Swift 试图把所有的指针和 C
风格的内存管理器都抽象出来。通常来说你不需要使用它们,除非你需要使用旧式(old-style)API(比如
CommonCrypto)。如果你真的如此不幸,那就需要学习如何处理它们:
在 Swift
中有两种类型的指针:UnsafePointers 和 UnsafeMutablePointers
类型。第一个用于常量寄存器,内存空间上的指针是恒定不变的;第二个用于可变的内存空间。对应到 C 语言,UnsafePointer
类型是”const type “缓冲类型,UnsafeMutablePointer 是”type “缓冲类型(这里的”缓冲”一词只是过去习惯的叫法)。指针的具体类型写在声明之后的<>中,所以如果你想去声明一个”void “类型的指针,需要写成:UnsafeMutablePointer 。如果要声明”const unsigned char “缓冲类型的指针,你需要使用:UnsafePointer
。虽然苹果确实提供了纯 C 类型到 Swift
类型的转换,但是一定要注意,CChar、CInt、CUnsignedLongLong…这样的类型不能直接用在 UnsafePointers
中,需要使用原生的 Swift 类型。这就出现一个问题,到底什么时候能用这些类型呢?我们需要深入一下 Swift 的类型定义:
typealias CShort = Int16typealias CSignedChar = Int8typealias
CUnsignedChar = UInt8typealias CUnsignedInt = UInt32typealias
CUnsignedLong = UInttypealias CUnsignedLongLong = UInt64typealias
CUnsignedShort = UInt16
值得庆幸的是我们不需要实现 UnsafePointers 和
UnsafeMutablePointers 类型的内存管理(只要你使用的是类似 NSData 这样的 Cocoa 对象)。Swift
会自动管理(和桥接)它们。如果你需要加密/解密数据并把密钥存到 NSData 中,那就可以调用 calling data.bytes 或者
data.mutableBytes 来获取对应的 UnsafePointer 和 UnsafeMutablePointer 指针。
另一种得到 UnsafePointer 变量的方式是 & 。处理输出变量时(需要内存的地址)就是通过&符号得到 Int 类型的 Unsafe(Mutable)Pointer 。我们可以在 CCCrypt 中使用这种方法把”Int”变量地址传给最后一个参数 :”dataOutMoved” 。注意:let 定义的变量对应 UnsafePointer 类型,var 变量对应 UnsafeMutablePointer 类型。
现在,我们已经拥有了调用 CCCrypt 所需的所有元素。
桥接
CommonCrypto 还没有兼容 Swift,所以为了使用它,我们需要通过头文件导入 Objective-C 形式的 CommonCrypto。
#import <CommonCrypto/CommonCrypto.h> SymmetricCryptor类
最近我需要做对称加密的项目,为了更容易的加密和解密数据,我建了一个 SymmetricCryptor 类(不要在意这个可怕的名字)。它可以把数据转换成恰当的 CommonCrypto 类型中。你可以使用它来方便的加密或解密数据。
let sc = SymmetricCryptor(algorithm: .AES128, options:
CCOptions(kCCOptionPKCS7Padding))cypher.setRandomIV()do { let cypherText
= try sc.crypt(string: clearText, key: key) } catch { print("Error
while encrypting: /(error)") }
CommonCrypto
提供了多种算法和设置,不过我只想解决最常见的加密问题,因此简化了配置。比如说,使用 RC4 的时候,你可以使用 40 或者 128
位的密钥(对应的常量是 RC4_40 和 RC4_128)。同理,AES 也有一些常用的常量(128b、256b……)。因此我定义了一个名为
SymmetricCryptorAlgorithm 的枚举变量,里面定了许多常见的配置(比如 AES
256),不仅包含算法,还包含很多其他信息,比如密钥长度和块大小。
在 SymmetricCryptor 的 GitHub 页面 中,你可以看到一个对称加密/解密示例,它展示了如何简单地实现对称加密/解密。
㈦ 如何使用rest插件检测content-type
基于webservice开发第三方应用程序,第三方API属于rest接口,而开发过程中难免需要测试,于是寻找测试rest接口的工具,现在主要用两种常用的工具:restclient和soupUI
一、使用restclient测试rest接口
RESTClient是一个用于测试RESTful Web services的Java客户端。
二、使用soapUI测试rest接口
虽然soapUI看上去好像是测试soap接口的,其实用它来测试rest接口未尝不可。
说明:目前只有test/xml格式成功实现,其他格式待探索。
soapUI由于目前消息体只有test/xml,multipart/form-data,application/xml,这三个选项,而在restclient工具中有几十种消息体格式,所以soapUI的使用还待进一步研究。
目前以合同添加接口为例
地址:
消息体类型是:text/xml,content-type=text/xml和charset=utf-8
方法是:POST
消息体:
<ContractInfo>
<adsContractState>0</adsContractState>
<applyNo>26</applyNo>
<contractAmount>550000</contractAmount>
<contractBeginTime>2012-08-13T10:55:04.336+08:00</contractBeginTime>
<contractEndTime>2013-08-13T10:55:04.336+08:00</contractEndTime>
<contractNo>20120026</contractNo>
<createTime>2012-08-13T10:55:04.336+08:00</createTime>
<departmentNo>0</departmentNo>
<depositAmount>120000</depositAmount>
<hasDeposit>1</hasDeposit>
<isFrameContract>0</isFrameContract>
<invoiceType>0</invoiceType>
<isHasFrameContract>0</isHasFrameContract>
<isUpdatedContract>0</isUpdatedContract>
<plan_id>0000026</plan_id>
<plan_name>pk</plan_name>
<projectNo>20120026</projectNo>
<salesmanName>赵玉梅</salesmanName>
<settlementContractState>1</settlementContractState>
<AdsInfo>
<parta_no>7</parta_no>
<parta_name>zymtest7</parta_name>
<partb_no>14</partb_no>
<partb_name>京东商城</partb_name>
<ads_amount>280000</ads_amount>
<has_deposit>1</has_deposit>
<deposit_amount>90000</deposit_amount>
<pay_account_deadline>2012-10-30</pay_account_deadline>
<last_charge_time>2012-10-30</last_charge_time>
</AdsInfo>
<AdsInfo>
<parta_no>8</parta_no>
<parta_name>zymtest8</parta_name>
<partb_no>14</partb_no>
<partb_name>京东商城</partb_name>
<ads_amount>220000</ads_amount>
<has_deposit>1</has_deposit>
<deposit_amount>40000</deposit_amount>
<pay_account_deadline>2012-09-30</pay_account_deadline>
<last_charge_time>2012-9-30</last_charge_time>
</AdsInfo>
</ContractInfo>
备注:其中<adsinfo>可以增加,增加整个list即可
操作步骤
1、打开soapUI,创建工程
如图,右键,点击New soapUI Project
2、弹出创建工程窗口
在project name中输入工程名称,如Test,rest 接口勾选Add REST Service(这个必须勾选),点击“OK”按钮
3、弹出创建新rest服务页面,输入接口的域名地址,勾选opens dialog to create a REST Resource,点击“OK”按钮
4、弹出New REST Resource窗口,输入名称输入resource URL,点击“OK”按钮
5、弹出 New REST Method窗口,输入方法名称,选择API方法,点击“OK”按钮
6、创建请求成功,request请求页面如下
7、选择消息体格式,输入认证密码,输入消息体:
8、执行,查看执行结果:
9、在outline界面可以修改参数:
㈧ rest系统前台访问是接口调用性能慢有什么优化思路和经验分享
rest系统前台访问是接口调用性能慢有什么优化思路和经验分享
访问REST资源
对于REST模块提供的接口可以参考用户手册的 REST API 章节,有着详细的介绍(包括URL和参数含义)。
2.1 身份认证
REST接口的大部分功能都需要验证,默认使用 Basic Access Authentication(基本连接认证) ,所以在访问资源时要在header中添加验证信息,当然为了安全期间把用户名和密码进行base 64位加密。
可以在用户登陆之后把用户名和密码进行加密并设置到session中,这样在前端就可以直接通过Ajax方式获取资源了:
import jodd.util.Base64;
String base64Code = "Basic " + Base64.encodeToString(user.getId() + ":" + user.getPassword());
session.setAttribute("BASE_64_CODE", base64Code);