首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> 關於VC++

VC++ 資料加密實作:對稱鍵與公開鍵加密演算法詳解

     編輯:關於VC++

前言

為確保資料傳輸安全與完整性,加密技術不可或缺。本文介紹兩類基本加密演算法——密鍵加密法(對稱式)與明鍵加密法(非對稱式)的原理與 VC++ 實作程式碼。

一、密鍵加密法(對稱式加密)

演算法可公開,但金鑰必須保密。不知金鑰者難以解密。基本流程:

  1. 將明文分割成等長區塊,長度等於金鑰長度,不足補空白
  2. 以自定整數對照表取代明文字元
  3. 對金鑰同樣進行對照取代
  4. 明文整數碼與金鑰整數碼相加,再對特定整數取模
  5. 結果整數碼再以字元對照表取代,得密文

實作程式碼

CString CEncryptDlg::Encrypt_Key(CString Source, CString Key)
{
    int iSourceLen = Source.GetLength();
    int iKeyLen = Key.GetLength();
    div_t div_Result = div(iSourceLen, iKeyLen);
    int iCount = div_Result.rem ? div_Result.quot + 1 : div_Result.quot;

    BYTE PWD_key[255] = {0};
    int j = 0;
    for (int i = 32; i <= 126; i++)  // 可列印 ASCII 範圍
        PWD_key[i] = j++;

    char pKey[255], pSource[255], pMid[255], strTarget[255];
    int n = 0;

    for (int i = 1; i <= iCount; i++) {
        CString strTmp = Source.Mid((i-1)*iKeyLen, iKeyLen);
        if (strTmp.GetLength() < iKeyLen)
            strTmp += CString(' ', iKeyLen - strTmp.GetLength());

        strcpy(pSource, strTmp);
        strcpy(pKey, Key);

        for (j = 1; j <= iKeyLen; j++) {
            int k1 = PWD_key[(BYTE)pKey[j-1]];
            int k2 = PWD_key[(BYTE)pSource[j-1]];
            int k = k1 + k2;
            div_Result = div(k, ENCRYPT_KEY);  // ENCRYPT_KEY 為自定常數
            k = div_Result.rem;
            pMid[j-1] = (char)k;
            strTarget[n++] = (char)k;
        }
    }

    for (j = 0; j < n; j++) {
        strTarget[j] += 32;
        if (strTarget[j] == 32) strTarget[j] = '*';  // 空白以 * 取代
    }
    strTarget[n] = '\0';
    return CString(strTarget);
}

註:取模運算的除數(ENCRYPT_KEY)可依需求調整以增強安全性。

二、明鍵加密法(非對稱式加密 / RSA 概念)

加密鍵公開,解密鍵保密。需一組鍵對:加密鍵 (e) 與解密鍵 (d)。流程:

  1. 選兩大質數 p、q(建議 100 位數以上),計算 r = p × q
  2. 選整數 e,與 (p-1)(q-1) 互質,e 為加密鍵
  3. 解方程 (d × e) mod ((p-1)(q-1)) = 1,得解密鍵 d
  4. 加密:c = p^e mod r(p 為明文字元碼,c 為密文)
  5. 解密:p = c^d mod r

加密實作

CString CEncryptDlg::Encrypt_KnownKey(CString Source)
{
    int r = ENCRYPT_P * ENCRYPT_Q;
    int e = 101;  // 加密鍵,大於 P、Q 的質數
    int k = (ENCRYPT_P-1) * (ENCRYPT_Q-1);
    int d = 5;    // 解密鍵,滿足 (d*e) mod k = 1

    char pSource[255], pTarget[255];
    int iLen = Source.GetLength();
    strcpy(pSource, Source);

    for (int i = 0; i < iLen; i++) {
        DWORD dw1 = Exp(pSource[i], e, r);  // 快速冪模運算
        div_t div_Result = div(dw1, r);
        pTarget[i] = (char)div_Result.rem;
    }
    pTarget[iLen] = '\0';
    return CString(pTarget);
}

解密實作

CString CEncryptDlg::Decode_KnownKey(CString Source)
{
    int r = ENCRYPT_P * ENCRYPT_Q;
    int k = (ENCRYPT_P-1) * (ENCRYPT_Q-1);
    int d = 5;  // 解密鍵

    char pSource[255], pTarget[255];
    int iLen = Source.GetLength();
    strcpy(pSource, Source);

    for (int i = 0; i < iLen; i++) {
        DWORD dw1 = Exp(pSource[i], d, r);
        div_t div_Result = div(dw1, r);
        pTarget[i] = (char)div_Result.rem;
    }
    pTarget[iLen] = '\0';
    return CString(pTarget);
}

輔助函數 Exp 需實作快速模冪運算(平方乘法),避免溢位。

結語

本文僅示範最基礎演算法核心,實務應用需考慮金鑰管理、填充模式、初始化向量、效能優化等議題。程式於 Windows XP + VC++ 6.0 測試通過。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved