Linux Kernel(Android) 加密算法總結(一)(cipher、compress、digest)

1. Linux內核支持哪些加密算法 ?

    內核支持的加密算法很多,包括:

    對稱加密算法,如AES,3DES;

    對稱密碼體制的發展趨勢將以分組密碼爲重點。分組密碼算法通常由密鑰擴展算法和加密(解密)算法兩部分組成。密鑰擴展算法將b字節用戶主密鑰擴展成r個子密鑰。加密算法由一個密碼學上的弱函數f與r個子密鑰迭代r次組成。混亂和密鑰擴散是分組密碼算法設計的基本原則。抵禦已知明文的差分和線性攻擊,可變長密鑰和分組是該體制的設計要點。  AES是美國國家標準技術研究所NIST旨在取代DES的21世紀的加密標準。   AES的基本要求是,採用對稱分組密碼體制,密鑰長度的最少支持爲128、192、256,分組長度128位,算法應易於各種硬件和軟件實現。1998年NIST開始AES第一輪分析、測試和徵集,共產生了15個候選算法。1999年3月完成了第二輪AES2的分析、測試。2000年10月2日美國政府正式宣佈選中比利時密碼學家Joan Daemen 和 Vincent Rijmen 提出的一種密碼算法RIJNDAEL 作爲 AES.   在應用方面,儘管DES在安全上是脆弱的,但由於快速DES芯片的大量生產,使得DES仍能暫時繼續使用,爲提高安全強度,通常使用獨立密鑰的三級DES。但是DES遲早要被AES代替。流密碼體制較之分組密碼在理論上成熟且安全,但未被列入下一代加密標準。 


    摘要算法,如sha1,md5;

    數據摘要算法是密碼學算法中非常重要的一個分支,它通過對所有數據提取指紋信息以實現數據簽名、數據完整性校驗等功能,由於其不可逆性,有時候會被用做敏感信息的加密。數據摘要算法也被稱爲哈希(Hash)算法或散列算法。

     SHA(Secure Hash Algorithm)是由美國專門制定密碼算法的標準機構—— 美國國家標準技術研究院(NIST)制定的,SHA系列算法的摘要長度分別爲:SHA爲20字節(160位)、SHA256爲32字節(256位)、 SHA384爲48字節(384位)、SHA512爲64字節(512位),由於它產生的數據摘要的長度更長,因此更難以發生碰撞,因此也更爲安全,它是未來數據摘要算法的發展方向。由於SHA系列算法的數據摘要長度較長,因此其運算速度與MD5相比,也相對較慢。

目前SHA1的應用較爲廣泛,主要應用於CA和數字證書中,另外在目前互聯網中流行的BT軟件中,也是使用SHA1來進行文件校驗的。
MD5(Message-Digest Algorithm 5,消息摘要算法版本5),它由MD2、MD3、MD4發展而來,由Ron Rivest(RSA公司)在1992年提出,目前被廣泛應用於數據完整性校驗、數據(消息)摘要、數據加密等。MD2、MD4、MD5 都產生16字節(128位)的校驗值,一般用32位十六進制數表示。MD2的算法較慢但相對安全,MD4速度很快,但安全性下降,MD5比MD4更安全、速度更快。
目前在互聯網上進行大文件傳輸時,都要得用MD5算法產生一個與文件匹配的、存儲MD5值的文本文件(後綴名爲 .md5或.md5sum),這樣接收者在接收到文件後,就可以利用與 SFV 類似的方法來檢查文件完整性,目前絕大多數大型軟件公司或開源組織都是以這種方式來校驗數據完整性,而且部分操作系統也使用此算法來對用戶密碼進行加密,另外,它也是目前計算機犯罪中數據取證的最常用算法。


     壓縮算法,如deflate。

 

     DEFLATE是同時使用了LZ77算法與哈夫曼編碼(Huffman Coding)的一個無損數據壓縮算法。它最初是由Phil Katz爲他的PKZIP歸檔工具第二版所定義的,後來定義在RFC 1951規範中。

        人們普遍認爲DEFLATE不受任何專利所制約,並且在LZWGIF文件格式使用)相關的專利失效之前,這種格式除了在ZIP文件格式中得到應用之外也在gzip壓縮文件以及PNG圖像文件中得到了應用。

        DEFLATE壓縮與解壓的源代碼可以在自由、通用的壓縮庫zlib上找到。


    不過內核好像不支持非對稱加密算法。


2. 加密算法源文件位置

     這些算法作爲加密函數框架的最底層,提供加密和解密的實際操作。這些函數可以在內核crypto文件夾下,相應的文件中找到。


3.  配置編譯選項將加密算法作爲模塊編入內核

   

Cryptographic options
加密選項

Cryptographic API
    提供核心的加密API支持.這裏的加密算法被廣泛的應用於驅動程序通信協議等機制中.子選項可以全不選,內核中若有其他部分依賴它,會自動選上

    Cryptographic algorithm manager
        創建加密模版實例,必須要選

    HMAC support
        爲IPSec所必須,可爲PPPoE提供壓縮支持
    Null algorithms
        NULL加密算法(什麼也不做),用於IPsec協議的封裝安全載荷模塊(ESP)
    MD4 digest algorithm
        老舊的摘要算法,已經過時
    MD5 digest algorithm
        主流摘要算法,128位(已被中國山東大學王小云攻破,可以快速找到碰撞)
    SHA1 digest algorithm
        主流摘要算法,160位(已被中國山東大學王小云攻破,可以快速找到碰撞),速度與MD5相當
    SHA256 digest algorithm
        更好的摘要算法,256位,速度較SHA1稍慢

    SHA384 and SHA512 digest algorithms
        更好的摘要算法,384/512位,速度大約只有SHA1的40-50%
    Whirlpool digest algorithms
        最安全的摘要算法,512位,已被列入ISO標準,目前最新版本爲3.0(2003年發佈)
    Tiger digest algorithms
        號稱最快的摘要算法,192位,專門爲64位CPU進行了優化
    ECB support
        電子密碼本,最簡單的加密方法
    CBC support
        密碼塊鏈,IPSec需要使用它
    DES and Triple DES EDE cipher algorithms
        老邁的(DES)和尚佳的(Triple DES)對稱加密算法
    Blowfish cipher algorithm
        又老又慢的對稱加密算法
    Twofish cipher algorithm
        很強的對稱加密算法,使用較廣
    Twofish cipher algorithms (i586)
        很強的對稱加密算法,使用較廣(針對i586的版本)
    Serpent cipher algorithm
        很強的對稱加密算法
    AES cipher algorithms
        最佳的對稱加密算法(Rijndael),128/192/256位,強度最高,快速且節省內存

    AES cipher algorithms (i586)
        最佳的對稱加密算法(Rijndael),128/192/256位,強度最高,快速且節省內存(針對i586的版本)
    CAST5 (CAST-128) cipher algorithm
        對稱加密算法
    CAST6 (CAST-256) cipher algorithm
        對稱加密算法
    TEA, XTEA and XETA cipher algorithms
        較弱的對稱加密算法
    ARC4 cipher algorithm
        脆弱的流對稱加密算法
    Khazad cipher algorithm
        對稱加密算法
    Anubis cipher algorithm
        對稱加密算法
    Deflate compression algorithm
        壓縮算法,當在IPSec中使用IPCOMP協議時才需要

    Michael MIC keyed digest algorithm
        摘要算法,僅僅用於校驗iSCSI設備傳輸的數據,因爲算法本身比較脆弱
    CRC32c CRC algorithm
        摘要算法,可用於校驗iSCSI設備傳輸的數據
    Testing module
        快速且醜陋的測試模塊
    Hardware crypto devices
        僅有VIA C7系列處理器支持硬件加密(VIA PadLock高級加密引擎)


參考:

    CryptoAPI support


     提供核心的加密API支持.這裏的加密算法被廣泛的應用於驅動程序通信協議等機制上,子選項可以全不選,內核中若有其他部分依賴它,會自動選

      (M)Cipher Algorithms

    創建加密模版實例,必須要選

     -- 128 bit blocksize

         (M) AES (aka Rijndael) cipher

         (M) Identity Function cipher

         (M) Crypto Devices

          (M) Loop Crypto support

4.  加密API 的調用方法:

    不過內核模塊不能直接調用這些函數,因爲它們並沒有export。內核提供一個統一的框架,來管理這些算法。

      加密算法通過crypto_register_alg()和crypto_unregister_alg()註冊。

      內核將加密算法分爲三類,1)cipher,2)compress,3)digest。

        加密函數框架中有相應的API封裝,提供給模塊調用。

對於使用這些加密函數,首先通過crypto_alloc_tfm()來分配一個加密函數對象的實例。初始化這些實例,然後就可以通過框架提供的API對數據進行加密和解密。完成以後,必須通過crypto_free_tfm()撤銷實例。

5.  代碼示例:


1)digest算法(sha1)
#include<linux/kernel.h>
#include <linux/module.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/gfp.h>
#include <linux/err.h>
#include <linux/syscalls.h>
#include <linux/slab.h>

struct crypto_tfm *tfm;
struct scatterlist sg[1];
char * code1="234123132513451345";
char * code2="234123132513451345";

char *do_digest(char* code){
    char *result;
    int code_len =strlen(code);
   
        tfm = crypto_alloc_tfm("sha1",0);
        if(IS_ERR(tfm))
                return 0;
        sg_init_one(sg,code,code_len);

        crypto_digest_init(tfm);
        crypto_digest_update(tfm,sg,1);
    result = (char*)kmalloc(sizeof(char)*50,GFP_KERNEL);

    if(result == NULL) {
        crypto_free_tfm(tfm);
        return 0;
    }
    memset(result,0,sizeof(char)*50);
    crypto_digest_final(tfm,result);
        crypto_free_tfm(tfm);
    return result;
}

static int __init test_init(void)
{
    char *result1,*result2;
    result1 = do_digest(code1);
    if(!result1)
        goto failed2;
    result2 = do_digest(code2);
    if(!result2)
        goto failed1;
   
    if(memcmp(result1,result2,50)!= 0)
        printk("<1>code1 != code2\n");
    else
        printk("<1>code1 == code2\n");
    kfree(result2);

failed1:
    kfree(result1);
failed2:
    return 0;
}

static void __exit test_exit(void)
{

}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("robert@cm");


2)compress算法(deflate)
#include<linux/module.h>
#include <linux/kernel.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/gfp.h>
#include <linux/err.h>
#include <linux/syscalls.h>
#include <linux/slab.h>

struct crypto_tfm *tfm;
char * code="Hello everyone, I'm robert from cm !";


static inline  void hexdump(unsignedchar*buf,unsignedint len){
    while(len--)
        printk("0x%02x,",*buf++);
    printk("\n");
}

static int __init test_init(void){
    int ret,result_len,temp_len;
    char result[512];
    char temp[512];

    printk("<1>%s\n",code);   
   
    /* Allocate transform for deflate */
            
    tfm = crypto_alloc_tfm("deflate",0);
        if(IS_ERR(tfm)){
        printk("<1>failed to load transform for deflate !\n");
                return 0;
    }

    memset(result,0,sizeof(result));

    temp_len = 512;
    ret = crypto_comp_compress(tfm,code,strlen(code),temp,&temp_len);
    if(ret){
        printk("<1>failed to compress !\n");
        return 0;
    }
      
    hexdump(temp,strlen(temp));
   
    memset(result,0,sizeof(result));

    result_len = 512;
    ret = crypto_comp_decompress(tfm,temp,strlen(temp),result,&result_len);
    if(ret){
                printk("<1>failed to decompress !\n");
                return 0;
        }

    printk("<1>%s\n",result);

    if(memcmp(code,result,strlen(code))!= 0)
        printk("<1>decompressed was not successful\n");
    else
        printk("<1>decompressed was successful\n");

           crypto_free_tfm(tfm);
    return 0;
}

static void __exit test_exit(void)
{

}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("robert@cm");


3)cipher算法(aes)
#include<linux/module.h>
#include <linux/kernel.h>
#include <linux/crypto.h>
#include <linux/scatterlist.h>
#include <linux/gfp.h>
#include <linux/err.h>
#include <linux/syscalls.h>
#include <linux/slab.h>
#include <linux/highmem.h>

struct crypto_tfm *tfm;
#if 1
char *code = "Hello everyone,I'm robert"
        "Hello everyone,I'm robert"
            "Hello everyone,I'm robert";

char *key = "00112233445566778899aabbccddeeff";
#endif

#if 0
char code[]={0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,
        0xbb,0xcc,0xdd,0xee,0xff};
char key[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,
        0x0b,0x0c,0x0d,0x0e,0x0f};
#endif

static inline  void hexdump(unsignedchar*buf,unsignedint len){
    while(len--)
        printk("%02x",*buf++);
    printk("\n");
}

static int __init test_init(void){
    int ret,templen,keylen,codelen;
    struct scatterlist sg[1];
    char *result;
    char *temp;

    keylen = 16;
    codelen = strlen(code)/2;
#if 0
    printk("<1>%s, codelen=%d\n",code,strlen(code));
    printk("<1>%s, keylen=%d\n",key,strlen(key));   
#endif   
    /* Allocate transform for AES ECB mode */
            
    tfm = crypto_alloc_tfm("aes",CRYPTO_TFM_MODE_ECB);
        if(IS_ERR(tfm)){
        printk("<1>failed to load transform for aes ECB mode !\n");
                return 0;
    }

    ret = crypto_cipher_setkey(tfm,key,keylen);
    if(ret){
        printk("<1>failed to setkey \n");
        goto failed1;
    }
   
    sg_init_one(sg,code,codelen);
        
    /* start encrypt */
   
    ret = crypto_cipher_encrypt(tfm,sg,sg,codelen);
    if(ret){
        printk("<1>encrypt failed \n");
        goto failed1;
    }
   
    temp = kmap(sg[0].page)+ sg[0].offset;

    hexdump(temp,sg[0].length);
   
          /* start dencrypt */
    templen = strlen(temp)/2;
    sg_init_one(sg,temp,templen);
    ret = crypto_cipher_decrypt(tfm,sg,sg,templen);
        if(ret){
                printk("<1>dencrypt failed \n");
                goto failed1;
        }

        result = kmap(sg[0].page)+ sg[0].offset;
    printk("<1>%s\n",result);
//        hexdump(result,sg[0].length);


#if 0
    if(memcmp(code,result,strlen(code))!= 0)
        printk("<1>dencrpt was not successful\n");
    else
        printk("<1>dencrypt was successful\n");
#endif
failed1:
           crypto_free_tfm(tfm);
    return 0;
}

static void __exit test_exit(void)
{

}

module_init(test_init);
module_exit(test_exit);

MODULE_LICENSE("GPL");

MODULE_AUTHOR("robert@cm");  

部分採用網絡代碼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章