㈠ 如何使用 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);