Files
xgcl/rsa/sdf_pkcs1v15.go
2026-05-27 23:03:00 +08:00

180 lines
6.0 KiB
Go

package rsa
import (
"math/big"
"xdx.jelly/xgcl/api/common"
"xdx.jelly/xgcl/gmath"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/identifier"
"xdx.jelly/xgcl/rsa/internal"
"xdx.jelly/xgcl/sm/sm4"
)
// GenerateKeyPairRSA corresponding to SDF_GenerateKeyPair_RSA
func (PKCS1v15) GenerateKeyPairRSA(keyBits uint32) (*PrivateKey, *PublicKey, error) {
if keyBits > common.RSAref_MAX_BITS {
return nil, nil, common.SDR_KEYERR
}
privateKey, err := internal.GenerateKey(grand.Reader, int(keyBits))
// privateKey, err := internal.GenerateKey(rand.New(rand.NewSource(1234)), int(keyBits))
if err != nil {
return nil, nil, common.SDR_KEYERR
}
return privateKey, &privateKey.PublicKey, nil
}
// GenerateEnvelopedKeyPairRSA 生成密钥对保护结构并用publicKey加密输出。
// 对应SDF_GenerateRSAKeyPairWithIPK_RSA和SDF_GenerateRSAKeyPairWithEPK_RSA
// 注意:内部不检查keyBits.
func (p PKCS1v15) GenerateEnvelopedKeyPairRSA(keyBits uint32, publicKey *PublicKey) (*common.EnvelopedRSAKey, error) {
sm4key := make([]byte, sm4.BlockSize)
n, err := grand.GenerateRandom(sm4key)
if n < sm4.BlockSize || err != nil {
return nil, common.SDR_RANDERR
}
sk, pk, err := p.GenerateKeyPairRSA(keyBits)
if err != nil {
return nil, err
}
enveloped := common.EnvelopedRSAKey{
SymmAlgID: identifier.SGDSM4ECB,
Bits: keyBits,
}
var data [common.RSAref_MAX_LEN]byte
buf := data[:]
buf0 := data[:common.RSAref_MAX_PLEN]
gmath.FillBytes(sk.N, buf)
copy(enveloped.EncryptedPriKey[0][:], buf[:common.RSAref_MAX_PLEN])
copy(enveloped.EncryptedPriKey[1][:], buf[common.RSAref_MAX_PLEN:])
gmath.FillBytes(new(big.Int).SetInt64(int64(sk.E)), buf)
copy(enveloped.EncryptedPriKey[2][:], buf[:common.RSAref_MAX_PLEN])
copy(enveloped.EncryptedPriKey[3][:], buf[common.RSAref_MAX_PLEN:])
gmath.FillBytes(sk.D, buf)
copy(enveloped.EncryptedPriKey[4][:], buf[:common.RSAref_MAX_PLEN])
copy(enveloped.EncryptedPriKey[5][:], buf[common.RSAref_MAX_PLEN:])
if len(sk.Primes) != 2 {
return nil, common.SDR_KEYERR
}
gmath.FillBytes(sk.Primes[0], buf0)
copy(enveloped.EncryptedPriKey[6][:], buf0)
gmath.FillBytes(sk.Primes[1], buf0)
copy(enveloped.EncryptedPriKey[7][:], buf0)
gmath.FillBytes(sk.Precomputed.Dp, buf0)
copy(enveloped.EncryptedPriKey[8][:], buf0)
gmath.FillBytes(sk.Precomputed.Dq, buf0)
copy(enveloped.EncryptedPriKey[9][:], buf0)
gmath.FillBytes(sk.Precomputed.Qinv, buf0)
copy(enveloped.EncryptedPriKey[10][:], buf0)
for i := 0; i < len(enveloped.EncryptedPriKey); i++ {
sm4.EncryptECB(enveloped.EncryptedPriKey[i][:], sm4key, enveloped.EncryptedPriKey[i][:])
}
err = pk.MarshalSDF(&enveloped.PubKey)
if err != nil {
return nil, common.SDR_UNKNOWERR
}
C, err := internal.EncryptPKCS1v15(grand.Reader, publicKey, sm4key)
if err != nil {
return nil, common.SDR_KEYERR
}
enveloped.L = uint32(len(C))
copy(enveloped.C[:], C)
return &enveloped, nil
}
// ImportEnvelopedKeyPairRSA 导入RSA密钥保护结构。
func (PKCS1v15) ImportEnvelopedKeyPairRSA(envelopedRSAKey *common.EnvelopedRSAKey, privateKey *PrivateKey) (*PrivateKey, *PublicKey, error) {
sk := internal.NewPrivateKey()
sm4key, err := internal.DecryptPKCS1v15(grand.Reader, privateKey, envelopedRSAKey.C[:envelopedRSAKey.L])
if err != nil || len(sm4key) != sm4.BlockSize {
return nil, nil, common.SDR_INARGERR
}
for i := 0; i < len(envelopedRSAKey.EncryptedPriKey); i++ {
sm4.DecryptECB(envelopedRSAKey.EncryptedPriKey[i][:], sm4key, envelopedRSAKey.EncryptedPriKey[i][:])
}
var data [common.RSAref_MAX_LEN]byte
buf := data[:]
copy(buf[:common.RSAref_MAX_PLEN], envelopedRSAKey.EncryptedPriKey[0][:])
copy(buf[common.RSAref_MAX_PLEN:], envelopedRSAKey.EncryptedPriKey[1][:])
sk.N.SetBytes(buf)
copy(buf[:common.RSAref_MAX_PLEN], envelopedRSAKey.EncryptedPriKey[2][:])
copy(buf[common.RSAref_MAX_PLEN:], envelopedRSAKey.EncryptedPriKey[3][:])
sk.E = int(new(big.Int).SetBytes(buf).Int64())
copy(buf[:common.RSAref_MAX_PLEN], envelopedRSAKey.EncryptedPriKey[4][:])
copy(buf[common.RSAref_MAX_PLEN:], envelopedRSAKey.EncryptedPriKey[5][:])
sk.D.SetBytes(buf)
sk.Primes[0].SetBytes(envelopedRSAKey.EncryptedPriKey[6][:])
sk.Primes[1].SetBytes(envelopedRSAKey.EncryptedPriKey[7][:])
sk.Precompute()
return sk, &sk.PublicKey, nil
}
// GenerateKeyRSA 生成会话密钥并用publicKey加密输出
func (PKCS1v15) GenerateKeyRSA(keyBits uint32, publicKey *PublicKey) ([]byte, []byte, error) {
key := make([]byte, keyBits)
c, err := internal.EncryptPKCS1v15(grand.Reader, publicKey, key)
if err != nil {
return nil, nil, common.SDR_KEYERR
}
return key, c, nil
}
// GenerateKeyRSA 导入会话密钥密文encryptedKey,并用privateKey解密。返回会话密钥。
func (PKCS1v15) ImportKeyRSA(keyBits uint32, privateKey *PrivateKey, encryptedKey []byte) ([]byte, error) {
key, err := internal.DecryptPKCS1v15(grand.Reader, privateKey, encryptedKey)
if err != nil || len(key) != int(keyBits) {
return nil, common.SDR_INARGERR
}
return key, nil
}
// ExchangeDigitEnvelopeRSA 基于RSA的数字信封转换,privateKey解密会话密钥密文,再用publicKey加密会话密文。
// inKey: 输入会话密钥密文
// 返回: 转换后的会话密文
func (PKCS1v15) ExchangeDigitEnvelopeRSA(privateKey *PrivateKey, publicKey *PublicKey, inKey []byte) ([]byte, error) {
key, err := internal.DecryptPKCS1v15(grand.Reader, privateKey, inKey)
if err != nil {
return nil, common.SDR_INARGERR
}
c, err := internal.EncryptPKCS1v15(grand.Reader, publicKey, key)
if err != nil {
return nil, common.SDR_KEYERR
}
return c, nil
}
// PublicKeyOperationRSA RSA公钥运算。数据格式由应用层封装。inData 应该小于 privateKey.Size()
func (PKCS1v15) PublicKeyOperationRSA(publicKey *PublicKey, inData []byte) ([]byte, error) {
return internal.PublicKeyOperationRSA(publicKey, inData)
}
// PrivateKeyOperationRSA RSA私钥运算。数据格式由应用层封装。inData 应该小于 privateKey.Bits/8
func (PKCS1v15) PrivateKeyOperationRSA(privateKey *PrivateKey, inData []byte) ([]byte, error) {
return internal.PrivateKeyOperationRSA(privateKey, inData)
}