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

在 SQL Server 中實作 RSA 加密演算法:純 T-SQL 版完整教學

     編輯:關於SqlServer

背景與限制

  • 純 T-SQL 實作 RSA,**僅供教學/演示/極小資料量加密**,**嚴禁生產環境敏感資料**。
  • SQL Server 內建 `ENCRYPTBYKEY`/`DECRYPTBYKEY` (對稱)、`ENCRYPTBYCERT`/`DECRYPTBYCERT` (非對稱)、`Always Encrypted`、`TDE` 為正規加密方案。
  • 本實作支援 Unicode (雙位元組字元),密文以 16 進位字串輸出。
  • **關鍵**:素數 `P, Q` 乘積 `N = P*Q` **必須大於最大 Unicode 碼點 (65535)**,否則中文加密會溢位錯誤。建議 `P, Q > 300` 以上。

核心物件建立腳本

1. 判斷素數函數


CREATE FUNCTION dbo.fn_IsPrime(@p INT) RETURNS BIT AS BEGIN
    DECLARE @i INT = 2, @flag BIT = 1;
    WHILE @i * @i <= @p BEGIN
        IF @p % @i = 0 BEGIN SET @flag = 0; BREAK; END
        SET @i += 1;
    END
    RETURN @flag;
END

2. 判斷互質 (最大公約數 = 1)


CREATE FUNCTION dbo.fn_IsCoprime(@a INT, @b INT) RETURNS BIT AS BEGIN
    DECLARE @tmp INT, @flag BIT = 1;
    WHILE @b % @a <> 0 BEGIN
        SET @tmp = @a; SET @a = @b % @a; SET @b = @tmp;
    END
    IF @a = 1 SET @flag = 0; -- GCD=1 互質
    RETURN @flag;
END

3. 產生金鑰對預存程序


CREATE PROC dbo.sp_GenRSAKeys @P INT, @Q INT AS BEGIN
    IF dbo.fn_IsPrime(@P) = 0 BEGIN PRINT @P + ' 非素數'; RETURN; END
    IF dbo.fn_IsPrime(@Q) = 0 BEGIN PRINT @Q + ' 非素數'; RETURN; END

    DECLARE @N BIGINT = @P * @Q, @T BIGINT = (@P - 1) * (@Q - 1), @E INT = 2;
    PRINT '可用金鑰對 (Public E, Private D):';
    WHILE @E < @T BEGIN
        IF dbo.fn_IsCoprime(@E, @T) = 0 BEGIN
            DECLARE @D INT = 2;
            WHILE @D < @N BEGIN
                IF (@E * @D) % @T = 1 
                    PRINT CAST(@E AS VARCHAR) + '    ' + CAST(@D AS VARCHAR);
                SET @D += 1;
            END
        END
        SET @E += 1;
    END
END

4. 加密函數 (字元逐一加密 → 6 位元 16 進位/字元)


CREATE FUNCTION dbo.fn_RSAEncrypt(@Plain NVARCHAR(100), @Key INT, @P INT, @Q INT) 
RETURNS NVARCHAR(4000) AS BEGIN
    DECLARE @Crypt NVARCHAR(4000) = N'', @N BIGINT = @P * @Q;
    DECLARE @Char NVARCHAR(1), @Code BIGINT, @K2 INT, @Val BIGINT, @Hex NVARCHAR(6);
    DECLARE @Pos INT = 1, @Len INT = LEN(@Plain);
    WHILE @Pos <= @Len BEGIN
        SET @Char = SUBSTRING(@Plain, @Pos, 1);
        SET @Code = UNICODE(@Char); -- Unicode 碼點
        SET @K2 = @Key / 2; SET @Val = 1;
        -- 快速模冪:平方乘演算法 (簡化版,實際應用二進位分解)
        WHILE @K2 > 0 BEGIN
            SET @Val = (CAST(POWER(@Code, 2) AS BIGINT) * @Val) % @N;
            SET @K2 -= 1;
        END
        SET @Val = (@Code * @Val) % @N; -- 最終乘一次
        -- 轉 6 位元 16 進位 (不足左補 0)
        SET @Hex = RIGHT('000000' + CONVERT(VARCHAR(6), @Val, 2), 6); -- Style 2 = 不含 0x 前綴
        SET @Crypt += @Hex;
        SET @Pos += 1;
    END
    RETURN @Crypt;
END

5. 解密函數


CREATE FUNCTION dbo.fn_RSADecrypt(@Cipher NVARCHAR(4000), @Key INT, @P INT, @Q INT) 
RETURNS NVARCHAR(4000) AS BEGIN
    DECLARE @Plain NVARCHAR(4000) = N'', @N BIGINT = @P * @Q;
    DECLARE @Hex6 NVARCHAR(6), @Val BIGINT, @K2 INT, @CharCode BIGINT;
    WHILE LEN(@Cipher) > 0 BEGIN
        SET @Hex6 = LEFT(@Cipher, 6);
        -- 16 進位字串轉數值
        SET @Val = CONVERT(BIGINT, @Hex6, 2); -- Style 2 直接支援
        SET @K2 = @Key / 2; SET @CharCode = 1;
        WHILE @K2 > 0 BEGIN
            SET @CharCode = (CAST(POWER(@Val, 2) AS BIGINT) * @CharCode) % @N;
            SET @K2 -= 1;
        END
        SET @CharCode = (@Val * @CharCode) % @N;
        SET @Plain += NCHAR(@CharCode);
        SET @Cipher = SUBSTRING(@Cipher, 7, LEN(@Cipher) - 6);
    END
    RETURN @Plain;
END

測試驗證


-- 選擇素數 P=1163, Q=59 (N=68617 > 65535)
EXEC sp_GenRSAKeys 1163, 59;
-- 輸出金鑰對範例:Public=779, Private=35039

CREATE TABLE #Test (Id INT IDENTITY, Cipher NVARCHAR(4000));
INSERT INTO #Test VALUES (dbo.fn_RSAEncrypt(N'中國人', 779, 1163, 59));
INSERT INTO #Test VALUES (dbo.fn_RSAEncrypt(N'Chinese', 779, 1163, 59));

SELECT *, Plain = dbo.fn_RSADecrypt(Cipher, 35039, 1163, 59) FROM #Test;
/* 結果:
Id  Cipher                                  Plain
1   00359B00E6E000EAF5                      中國人
2   01075300931B0010A4007EDC004B340074A6004B34  Chinese
*/

效能與安全性警示

維度現狀生產級要求
演算法教科書級 RSA (無填充/OAEP)RSA-OAEP / ECIES
金鑰長度~16 bits (N~68617)≥ 2048 bits (N ~ 617 位數)
速度字元級迴圈,極慢硬體加速 / 原生實作
抗攻擊極易破解 (小數分解)抗量子/側信道
用途教學、極小非敏感標籤金融、個資、機密

正確生產加密選型

  • **對稱加密 (大量資料)**:`CREATE SYMMETRIC KEY` + `AES_256` + `ENCRYPTBYKEY`/`DECRYPTBYKEY`。
  • **非對稱加密 (金鑰交換/簽章)**:`CREATE CERTIFICATE` / `ASYMMETRIC KEY` (RSA 2048/4096) + `ENCRYPTBYCERT`/`DECRYPTBYCERT` / `SIGNBYCERT`/`VERIFYSIGNEDBYCERT`。
  • **應用層加密**:.NET `System.Security.Cryptography` / Java `javax.crypto`,金鑰由 KMS/HSM 管理,資料庫僅存密文。
  • **Always Encrypted**:敏感欄位客戶端加密,資料庫不可解密,最高安全等級。

總結

純 T-SQL 實作 RSA 是理解非對稱加密數學原理的絕佳教具,但**絕不可用於真實保護**。掌握素數判斷、模冪運算、擴展歐幾里得算法 (求模逆) 核心步驟,轉而使用平台內建強加密 API,才是專業開發者的正確姿態。

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