HTTP Basic Authentication, 基于HTTP規範的認證方式,username和password會以base64加密後存入header的Authentication.
Reference:維基的解釋 spring security的實作
---------------------------------------------------------
WS Security 以下為轉載:
從web service security的角度來探讨一下.必須聲明的是,我并不是在解讀 ws-security 規範, 從某種意義上來說,是在學習Java Security.
從web service的應用場景來說, 要從endpoint A 發送 SOAP message 到 endpoint B. 一般情況下, 如果我們要保證這個soap message資訊的安全,主要會從以下三個方面來考慮,闡述.
- 保密性(Confidentiality)
- 完整性(Integrity)
- 真實性(Authenticity)
我們接下來挨個來看下,是怎麼滿足這三個需求的,以及在JDK中,分别提供了什麼樣的API來于之對應.
保密性(Confidentiality)
從大的分類來看,我們有兩大種加密技術,分别是對稱加密(symmetric encryption)和非對稱加密(asymmetric encryption).
對稱加密(symmetric encryption)
對稱加密是一個比較早的一種加密方式.比如說Alice要發送一個消息跟Bob,那麼他們之前就應該說定了一個secret key,然後Alice把資訊用這個secret key進行加密. 當資訊到達Bob的時候, Bob再利用這個secret key來把它解密.這種加密方式,可以是對每個bit進行加密,也可以是對block(chunk of bit, 比如64-bit)進行加密. 如果在是選擇block加密的話,就得有一個補足(Padding)的概念,就比如說不夠64-bit,你用0或者其他的來補足成一個block.在Java中, Cipher類是負責加密,解密的.在對稱加密中,需要以下三個屬性.1) 加密模式, 比如(ECB -Encryption Code Book, CBC, CFB, OFB, PCBC)2) 加密算法, 比如(DES- Data Encryption Standard, TripleDES, AES, RC2, RC4, RC5, Blowfish, PBE)3) 補足方式, 比如(No padding, PKCS5, OAEP, SSL3)
我們下面這個例子就是使用Java的Cipher類來加密.
KeyGenerator keygen = KeyGenerator.getInstance("DES");
keygen.init(56);
SecretKey key = keygen.generateKey();
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = cipher.doFinal("This is clear text".getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] clearText = cipher.doFinal(cipherText);
先是生成一個56的DES的加密鑰匙, 然後采用DES算法, ECB加密模式, PKCS5Padding補足方式來加密.
非對稱加密(Asymmetric Encryption)
對稱加密存在的一個主要問題在于怎麼安全的配發這個密鑰給Alice和Bob呢?是以,我們後來引入了這個非對稱加密,可以說現在這個是一個很普遍的加密方法.非對稱加密主要是他有兩把鑰匙, 公鑰(Public Key)和私鑰(Private Key),這兩把鑰匙是配對的. 一樣的情況, Alice想發送資訊給Bob, 那麼流程就如下:
Alice使用Bob的公鑰加密資訊 -> 加密過的資訊 -> Bob用他自己的私鑰解密.
這種情況下,大家隻需要把公鑰放在一個信任的機構(CA,例如Verisign),把私鑰保留在自己手上,那麼就解決了對稱加密中密鑰的配發問題.當然了,這個非對稱加密的偉大之處還在于如果你沒有私鑰,至少在你的有生之年是無法破解的.非對稱加密的算法主要有兩種: RSA 和 Diffie-Hellman. RSA是最為廣泛使用的一種加密算法.相對應的,我們就得使用keypair來加密解密,代碼如下:
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair keypair = keyGen.generateKeyPair();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, keypair.getPublic());
byte[] cipherText = cipher.doFinal("This is clear text".getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, keypair.getPrivate());
byte[] clearText = cipher.doFinal(cipherText);
不同的是,我們用公鑰加密,然後用私鑰來解密. 當然了,我們也可以用私鑰加密,然後公鑰來解密,這在我們後面的數字簽名中會用到.
完整性(Integrity)
我們可以用加密的手段對資訊進行了加密,那麼保證這個資訊的明文不會被其他人看到,但是我們怎麼來保證說這個發過來的資訊就是完整的呢?那麼我們這裡就因為一個叫資訊摘要(Message Digest)的概念,所謂的資訊摘要就是說用一個摘要算法,把資訊生成一串字元,可以算是資訊的足迹(fingerprint of the message). 這種算法是一個單方向的,也就是說,從生成的字元想倒推到原來的這個資訊,那幾乎是不可能的.這個算法的另外一個特點是,隻要你對資訊做一個小小的改動,那麼生成的字元串差别就很明顯.常見的消息摘要(Message-digest)算法有: MD2, MD5 (128位的算法), SHA-1 (160位的算法)在Java中,MessageDigest類來負責資訊摘要,使用大緻如下:
MessageDigest messageDigest = MessageDigest.getInstance("MD5");
messageDigest.update("TestMessage".getBytes("UTF-8"));
System.out.println(new String(messageDigest.digest(), "UTF-8"));
真實性(Authenticity)
上面我們解決了保密性和完整性,那我們怎麼來保證Bob收到的這個資訊就是Alice發的嗎?有可能是Eva借用Alice的名字,拿到Bob的公鑰發的.基于這個考慮,我們就引入了一個數字簽名(Digital Signature)的概念.數字簽名就是在你發送資訊的時候,用你的私鑰進行加密,實際應用中,會對資訊摘要進行數字簽名,那麼當Bob收到這個被數字簽名過的資訊摘要時,用Alice的公鑰去解密,就可以确定這個消息是來自于Alice.數字簽名的算法有兩種: RSA, DSA(Digital Signature Algorithm). 注意, RSA算法,既可用于加密,也可以用于數字簽名. 但是DSA隻可用于數字簽名.JDK支援以下的組合, MD2/RSA, MD5/RSA, SHA1/DSA, SHA1/RSA.下面我們直接看JDK中Siganiture類來簽名的使用.
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair keypair = keyGen.generateKeyPair();
Signature sig = Signature.getInstance("MD5WithRSA");
sig.initSign(keypair.getPrivate());
sig.update("This is message".getBytes("UTF-8"));
byte[] signature = sig.sign();
//Verify the signature
sig.initVerify(keypair.getPublic());
sig.update("This is message".getBytes("UTF-8"));
if (sig.verify(signature)) {
System.out.println("Signature verified.");
}
到目前為止,我們介紹了加密,資訊完整,數字簽名這三個概念,應該說可以是完成了,你都懂了.
但是,等等,你是不是在經常聽到說證書,X.509, keytool, keystore等等的概念呢?下面,我們再來依次看看這幾個概念.
證書(certificates) and X.509
之前我們說,在這種非對稱加密算法中,我們一般會把公鑰放在一個另外一個機構,這個機構專門負責來保管你的公鑰,而且這個機構還負責核實你的真實性. 那麼他一旦核實你後,就會建立一個東西,這個東西包含了你的公鑰,你的個人資訊(Identity),然後再用這個機構的私鑰進行數字簽名. 我們管這個東西就叫數字證書. 我們管這樣的機構叫做CA( Certificate Authority)X.509是一種存儲證書的标準,我們通常直接叫X.509證書.
keytool, keystore
keystore是用來存放鑰匙(包括公鑰,私鑰),證書的容器. keystore是一個以.keystore為字尾名的檔案.在keystore裡面的鑰匙和證書可以有名字,叫做alias. 而且他們各自可以有密碼保護.
JDK自帶的keytool是用來建立keystore以及key的工具,下面我們來看幾個常用的指令.
1) 建立keys (注意不能換行).
2)導出證書keytool -genkey -alias serverkey -keypass serverpass -keyalg RSA -sigalg SHA1withRSA -keystore server.keystore -storepass nosecretkeytool -genkey -alias clientkey -keypass clientpass -keyalg RSA -sigalg SHA1withRSA -keystore client.keystore -storepass nosecret
3)導入證書keytool -export -alias serverkey -keystore server.keystore -storepass nosecret -file servercert.cer
keystore, truststore的差別#####keytool -import -alias serverkey -keystore client.keystore -storepass nosecret -file servercert.cer
在跟web service 打交道,或者做測試的時候,你會經常聽到trust store這個詞,他其實就是一個CA,他是專門存放public key的; keystore是既存放public key,也存放private key的.這個貼子上, Jason詳細的解釋了在ws security中,keystore和truststore的配置問題.