Java網絡安全(一)

消息摘要是數據信息的數字指紋。通過某種安全散列算法(如SHA1)對數據信息進行加密,就可以生成一個20字節(MD5算法好像是16字節)的序列,這個序列就稱爲消息摘要。

  從安全的角度考慮,我們總是希望任何不同的數據信息都生成不同的消息摘要,但這是不可能的,就拿SHA1算法來說,消息摘要是一個20字節的序列,也就是160位的長度,一共也只有2的160次方種可能。但這已經是一個巨大的數字了,我們可以相信兩個不同的數據信息總是生成不同的消息摘要。

  所以,消息摘要具有以下兩個特點:
  • 如果數據信息改變了,那麼消息也將根着改變;
  • 僞造者無法創建與原數據信息具有相同消息摘要的假數據信息。

  消息摘要在網絡中怎樣起到安全的作用呢?假設你要發送下面一段數據信息給你的朋友:
晚上一起吃飯

  你可以先生成這段數據信息的消息摘要,上面的信息用SHA1算法加密後就復到下面的消息摘要:
fa00078d5bd477e6d397dd5f7f11166a

  之後你就可以把數據和摘要分別發送給你的朋友,然後你朋友也對數據信息進行加密,並把加密生成的摘要與你發送給他的進行對比,如果一樣的,那麼你朋友就可以確定數據信息在傳輸過程中沒有被別人修改過。

  當然,僅僅是靠消息摘要,還無法解決所有的安全問題,比如數據和摘要在傳輸過程中同時被別人竊取了,你的朋友無法保正數據是不是真的來自於你,等等。後面的文章,我們接着介紹如果通過別的方法(比如公共密鑰)來解決其它的安全問題。

  下面我們來看看在Java中如何對數據進行SHA1算法或MD5算法加密。其實Java語言已經實現了這兩個算法,那就是java.security包下的MessageDigest類。具體的代碼網上很容易搜到現在的代碼:
public static String encodePassword(byte[] data, String algorithm)
        throws NoSuchAlgorithmException
{
    MessageDigest md = MessageDigest.getInstance(algorithm);

    md.reset();
    md.update(data);

    byte[] rlt = md.digest();

    StringBuffer buf = new StringBuffer();

    for (int i = 0; i < rlt.length; i++)
    {
        if ((rlt[i] & 0xff) < 0x10)
        {
            buf.append("0");
        }

        buf.append(Integer.toHexString(rlt[i] & 0xff));
    }

    return buf.toString();
}

  首先通過MessageDigest類的getInstance(String)方法獲得該類的一個實例,具體的算法通過參數指定,比如"SHA-1"或"MD5",reset()方法用於復位摘要,update方法以字節數組的方式指定要加密的數據信息,接着調用digest()方法就生成了消息摘要。

  比較有意思的是後面for塊裏面的代碼,我第一次看這段代碼的時候也是花了點功夫才弄明白。

  後面這部分代碼的作用是把byte[]格式的摘要轉換成16進制的字符串。在Java中,byte佔有8個位,轉換成16進制的話,也就是2位,所以當這個byte小於16的話,要在前面加一個0。比如2進制數00001111,應該是轉換成0f,但如果直接調用Integer.toHexString(15)的話,返回的結果是f而不是0f。這就是爲什麼上面if後面要做<0x10的判斷了。

  另外一個比較難懂的地方就是rlt[i] & 0xff了。這裏的與操作,目的很簡單,就是把byte正確的轉型爲int,因爲toHexString(int)方法只能接受int類型的參數。如果我們不做這個與操作,某些情況下轉型過後的值就可能不是我們想要的值,比如-1的字節碼(補碼,Java以補碼的形式表示數值)爲
1111 1111

  轉型爲int後的字節碼是
1111 1111 1111 1111 1111 1111 1111 1111

  而在這裏我們需要的值是
0000 0000 0000 0000 0000 0000 1111 1111

  所以這裏用rit[i]和0xff做了一個與運算,就能得到我們想要的值了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章