1. 程式人生 > >SM2非對稱演算法加解密

SM2非對稱演算法加解密

在前面文章我們已經可以製作SM2證書了,主要應用了SM2簽名驗證演算法和SM3摘要演算法,在本文中主要介紹SM2公鑰加密演算法。這裡我們使用SM2數字證書來做SM2非對稱加密,然後使用硬體加密裝置做解密,比如加密檔案只能由指定的智慧密碼鑰匙UKey才能解開。

SM2加密演算法

SM2加密同樣使用接收方公鑰加密,公鑰由一個曲線座標點組成,在X.509證書中的共鑰表示為04標記開始的2個32byte的BigInteger,即曲線點P(x,y)。SM2公鑰加密演算法比RSA相對複雜,加密結果由3個部分組成,SM2加密過程中使用了隨機數,因此同樣的明文資料每一次加密結果都不一樣。SM2加密演算法流程如下圖所示。

根據國密推薦的SM2橢圓曲線公鑰密碼演算法,首先產生隨機數計算出曲線點C1,2個32byte的BigInteger大數,即為SM2加密結果的第1部分。第2部分則是真正的密文,是對明文的加密結果,長度和明文一樣。第3部分是雜湊值,用來效驗資料。按國密推薦的256位橢圓曲線,明文加密結果比原長度會大96byte。

SM2加密演算法同樣也可以基於使用BouncyCastle庫實現。一般使用數字證書來標識身份,同時使用證書中公鑰加密資料。如下SM2Cipher類是C#下SM2軟演算法實現。

SM2Cipher.cs 1publicclass SM2Cipher 2{ 3private
int ct =1; 4 5private ECPoint p2; 6private SM3Digest sm3keybase; 7private SM3Digest sm3c3; 8 9privatebyte[] key =newbyte[32]; 10privatebyte keyOff =0; 11 12public SM2Cipher() { } 13 14 15 16privatevoid Reset() 17{ 18 sm3keybase =new SM3Digest(); 19 sm3c3 =new SM3Digest();
20 21byte[] p; 22 23 p = p2.X.ToBigInteger().ToByteArrayUnsigned(); 24 sm3keybase.BlockUpdate(p, 0, p.Length); 25 sm3c3.BlockUpdate(p, 0, p.Length); 26 27 p = p2.Y.ToBigInteger().ToByteArrayUnsigned(); 28 sm3keybase.BlockUpdate(p, 0, p.Length); 29 30 ct =1; 31 NextKey(); 32 }
33 34privatevoid NextKey() 35{ 36 SM3Digest sm3keycur =new SM3Digest(sm3keybase); 37 sm3keycur.Update((byte)(ct >>24&0x00ff)); 38 sm3keycur.Update((byte)(ct >>16&0x00ff)); 39 sm3keycur.Update((byte)(ct >>8&0x00ff)); 40 sm3keycur.Update((byte)(ct &0x00ff)); 41 sm3keycur.DoFinal(key, 0); 42 keyOff =0; 43 ct++; 44 } 45 46publicvirtual ECPoint InitEncipher(ECPoint userKey) 47{ 48 BigInteger k =null; 49 ECPoint c1 =null; 50 51if (1==1) 52{ 53 AsymmetricCipherKeyPair key = SM2CryptoServiceProvider.SM2KeyPairGenerator.GenerateKeyPair(); 54 ECPrivateKeyParameters ecpriv = (ECPrivateKeyParameters)key.Private; 55 ECPublicKeyParameters ecpub = (ECPublicKeyParameters)key.Public; 56 57 k = ecpriv.D; 58 c1 = ecpub.Q; 59 } 60 61 p2 = userKey.Multiply(k); 62 Reset(); 63 64return c1; 65 66 } 67 68publicvirtualvoid Encrypt(byte[] data) 69{ 70 sm3c3.BlockUpdate(data, 0, data.Length); 71for (int i =0; i < data.Length; i++) 72{ 73if (keyOff == key.Length) 74 NextKey(); 75 76 data[i] ^= key[keyOff++]; 77 } 78 } 79 80publicvirtualvoid InitDecipher(BigInteger userD, ECPoint c1) 81{ 82 p2 = c1.Multiply(userD); 83 Reset(); 84 } 85 86publicvirtualvoid Decrypt(byte[] data) 87{ 88for (int i =0; i < data.Length; i++) 89{ 90if (keyOff == key.Length) 91 NextKey(); 92 93 data[i] ^= key[keyOff++]; 94 } 95 sm3c3.BlockUpdate(data, 0, data.Length); 96 } 97 98publicvirtualvoid Dofinal(byte[] c3) 99{ 100byte[] p = p2.Y.ToBigInteger().ToByteArrayUnsigned(); 101 sm3c3.BlockUpdate(p, 0, p.Length); 102 sm3c3.DoFinal(c3, 0); 103 Reset(); 104 }105106107///<summary>108/// 使用SM2公鑰加密資料 109///</summary>110///<param name="pubKey"></param>111///<param name="plaintext"></param>112///<returns></returns> 113publicstring Encrypt(ECPoint pubKey, byte[] plaintext) 114{ 115116byte[] data =newbyte[plaintext.Length]; 117 Array.Copy(plaintext, data, plaintext.Length); 118119 ECPoint c1 = InitEncipher(pubKey); 120 Encrypt(data); 121122byte[] c3 =newbyte[32]; 123 Dofinal(c3); 124125string hexString = c1.X.ToBigInteger().ToString(16) + c1.Y.ToBigInteger().ToString(16) 126+ Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(data) 127+ Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(c3); 128129return hexString; 130131 }132133///<summary>134/// 使用SM2解密資料 135///</summary>136///<param name="privateKey"></param>137///<param name="ciphertext"></param>138///<returns></returns> 139publicbyte[] Decrypt(BigInteger privateKey, string ciphertext) 140{ 141142string hexString = ciphertext; 143string c1X = hexString.Substring(0, 64); 144string c1Y = hexString.Substring(0+ c1X.Length, 64); 145string encrypData = hexString.Substring(c1X.Length + c1Y.Length, hexString.Length - c1X.Length - c1Y.Length -64); 146string c3 = hexString.Substring(hexString.Length -64); 147148byte[] data = SM2CryptoServiceProvider.StrToToHexByte(encrypData); 149150 ECPoint c1 = CreatePoint(c1X, c1Y); 151152 InitDecipher(privateKey, c1); 153 Decrypt(data); 154155byte[] c3_ =newbyte[32]; 156 Dofinal(c3_); 157158string decryptData = Encoding.Default.GetString(data); 159bool isDecrypt = Org.BouncyCastle.Utilities.Encoders.Hex.ToHexString(c3_) == c3; 160161return (isDecrypt ? data : newbyte[0]); 162 }163164165///<summary>166/// 建立座標點 167///</summary>168///<param name="x"></param>169///<param name="y"></param>170///<returns></returns> 171publicstatic ECPoint CreatePoint(

相關推薦

SM2對稱演算法解密

在前面文章我們已經可以製作SM2證書了,主要應用了SM2簽名驗證演算法和SM3摘要演算法,在本文中主要介紹SM2公鑰加密演算法。這裡我們使用SM2數字證書來做SM2非對稱加密,然後使用硬體加密裝置做解密,比如加密檔案只能由指定的智慧密碼鑰匙UKey才能解開。 SM2加

JAVA RSA對稱分段解密

我就不講原理了 直接開擼程式碼 祕鑰對生成,專案根目錄生成一個檔案。 也可直接取打印出來的私鑰和公鑰 import java.io.FileOutputStream; import java.io.ObjectOutputStream; import java

國密SM2對稱演算法與實現

         國密SM2演算法標準包括4個部分,第1部分為總則,主要介紹了ECC基本的演算法描述,包括素數域和二元擴域兩種演算法描述,第2部分為數字簽名演算法,這個演算法不同於ECDSA演算法,其計算量大,也比ECDSA複雜些,也許這樣會更安全吧,第3部分為金鑰交換協

Openssl aes對稱加密演算法 解密例程 1

前面我們用openssl的aes256對稱加密演算法對16個位元組的記憶體塊進行了的加解密運算測試,現在更進一步,對指定大小的記憶體塊進行加解密運算。 首先明確一下aes是分組加密演算法,且每次加密的記憶體塊是16個位元組,所以,我們需要加密的記憶體塊必須是16個位元組的整數倍,若不是,則需要進行補齊。

記一次RSA對稱演算法的排坑經歷

Map<String,Object> encryParam = new HashMap<>(5); encryParam.put("connectorUrl",

RSA演算法解密(JAVA)

/** * RSA加密演算法的演示驗證 * RSA是一種分組加密演算法 * 注意:金鑰對採用的長度決定了加密塊的長度,我這裡取的是2048,即256byte * 由於加密塊的長度固定為256,因此明文的長度至多為256 - 11 = 245byte * 我這裡明文

Java利用 AES/ECB/PKCS5Padding 演算法解密

Java利用  AES/ECB/PKCS5Padding 演算法加解密。 package com.newland.njwpayment.utils;   import javax.crypto.Cipher;   import javax.crypto.spec.

RSA演算法解密---crypto++庫和OpenSSL庫

1. OpenSSL庫 a、 方式一: #include<string.h>#include <openssl/rsa.h>#pragma comment(lib,"libeay32.lib")#pragma comment(lib,"ssleay3

區塊鏈基礎:對稱演算法

1.Hash演算法 package cn.hadron.security; import java.security.MessageDigest; import java.util.UUID; import org.eclipse.jetty.

Java結合keytool實現對稱加密和解密

非對稱加密 ascii 表示 import enc 通信 vat 方法 ports 在Java安全體系中,簽名屬於JAAS模塊,加解密屬於JCE模塊。keytool的使用keytool是JDK自帶的一個密鑰庫管理工具。這裏只用到了keytool的部分功能,包括生成密鑰對,導

VC 使用Cryptography 微軟自帶演算法解密檔案

// Encrypting_a_File.cpp : Defines the entry point for the console // application. // #include <tchar.h> #include <stdio.h>

SM2對稱解密java工具類

由於工作原因需要對原有加密方式RSA已不適用,要支援國密SM2 maven依賴 <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov

RSA對稱解密演算法的使用

加密金鑰和解密金鑰相同時則稱為對稱加密。由於加密金鑰和解密金鑰相同,它們也被稱為Shared Key。如AES等。 加密金鑰(公鑰)和解密金鑰(私鑰)不相同時則稱為非對稱加密,別稱公鑰密碼。如RSA等。 非對稱加密例子: 假設張三擁有的公鑰Pu和私鑰Pr,其公鑰是公開的,誰

.NET Core解密實戰系列之——RSA對稱加密演算法

![](https://img2020.cnblogs.com/blog/2029875/202006/2029875-20200612165254059-1754283874.png) --- [TOC] ## 簡介 加解密現狀,編寫此專案的背景: - 需要考慮系統環境相容性問題(Linux、Wi

對稱對稱解密

32位 tro 進行 ont 什麽 金融 被鎖 方式 str 對稱 DES: DES算法 再大多運用在 如信用卡持卡人的PIN的加密傳輸,IC卡與POS間的雙向認證、金融交易數據包的MAC校驗等領域 DES算法的入口參數有三

php openssl_sign() 語法+RSA公私鑰加密解密,對稱加密演算法詳解

其實有時候覺得寫部落格好煩,就個函式就開篇部落格。很小的意見事情而已,知道的人看來多取一舉,或者說沒什麼必要,浪費時間,不知道的人就會很鬱悶。技術就是這樣的,懂的人覺得真的很簡單啊,不知道的人真的好難。。。 一般在跟第三方介面對接資料的時候,為了保證很多都使用的RSA簽名,沒性趣瞭解的同學只需要

iOS-RSA對稱解密

實驗目標 程式語言不限 至少實現RSA生成公私鑰,並儲存為金鑰檔案,最好是ECC演算法 明文“學號+姓名+專業+學院” 使用其中一種金鑰加密,輸出密文 解密密文,輸出明文 調研PKI公鑰體系,在報告中說明,如何用公私鑰實現PKI體系 簡述E

RSA對稱加密演算法(表單提交時,前端js加密,後端java解密)

RSA非對稱加密演算法(表單提交時,前端js加密,後端java解密 非對稱加密演算法 需要的工具 前端jsp頁面 js程式碼 加密解密的工具類 產生公鑰的類 處理登陸請求的類 加密成功的密碼 非對稱加密演算

軟實現對稱解密,公鑰證書與公鑰值區別,包含提取公約值程式碼

目前有部分未採購簽名驗籤伺服器的企業,採用軟實現做非對稱、對稱加解密,本文簡略說明一下工作過程中遇到的問題。 本交易涉及傳送方,接收方 問題背景: 對方即接收方採用的是軟實現,並且只提供了公鑰值(未經CA簽發) 我方即傳送方,採用的是硬體簽名驗籤服務。伺服器中存有我方的私鑰,

JAVA密碼加密演算法.RSA演算法(對稱加密演算法)和密碼鹽MD5

密碼加鹽MD5 Message Digest Algorithm MD5(中文名為訊息摘要演算法第五版)為電腦保安領域廣泛使用的一種雜湊函式,用以提供訊息的完整性保護。 是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、雜湊演算法),主流程式語言普遍已有MD5實現。將資料(如漢字)運