180 lines
6.0 KiB
Go
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)
|
|
}
|