gitee.com/lh-her-team/common@v1.5.1/helper/libp2pcrypto/rsa_go.go (about) 1 //go:build !openssl 2 // +build !openssl 3 4 package libp2pcrypto 5 6 import ( 7 "crypto" 8 "crypto/rand" 9 "crypto/rsa" 10 "crypto/x509" 11 "errors" 12 "io" 13 "sync" 14 15 "gitee.com/lh-her-team/common/helper/libp2pcrypto/pb" 16 17 "github.com/minio/sha256-simd" 18 ) 19 20 // RsaPrivateKey is an rsa private key 21 type RsaPrivateKey struct { 22 sk rsa.PrivateKey 23 } 24 25 // RsaPublicKey is an rsa public key 26 type RsaPublicKey struct { 27 k rsa.PublicKey 28 cacheLk sync.Mutex 29 cached []byte 30 } 31 32 func NewRsaPublicKey(k rsa.PublicKey) *RsaPublicKey { 33 return &RsaPublicKey{k: k} 34 } 35 36 // GenerateRSAKeyPair generates a new rsa private and public key 37 func GenerateRSAKeyPair(bits int, src io.Reader) (PrivKey, PubKey, error) { 38 if bits < MinRsaKeyBits { 39 return nil, nil, ErrRsaKeyTooSmall 40 } 41 priv, err := rsa.GenerateKey(src, bits) 42 if err != nil { 43 return nil, nil, err 44 } 45 pk := priv.PublicKey 46 return &RsaPrivateKey{sk: *priv}, &RsaPublicKey{k: pk}, nil 47 } 48 49 // Verify compares a signature against input data 50 func (pk *RsaPublicKey) Verify(data, sig []byte) (bool, error) { 51 hashed := sha256.Sum256(data) 52 err := rsa.VerifyPKCS1v15(&pk.k, crypto.SHA256, hashed[:], sig) 53 if err != nil { 54 return false, err 55 } 56 return true, nil 57 } 58 59 func (pk *RsaPublicKey) Type() pb.KeyType { 60 return pb.KeyType_RSA 61 } 62 63 // Bytes returns protobuf bytes of a public key 64 func (pk *RsaPublicKey) Bytes() ([]byte, error) { 65 pk.cacheLk.Lock() 66 var err error 67 if pk.cached == nil { 68 pk.cached, err = MarshalPublicKey(pk) 69 } 70 pk.cacheLk.Unlock() 71 return pk.cached, err 72 } 73 74 func (pk *RsaPublicKey) Raw() ([]byte, error) { 75 return x509.MarshalPKIXPublicKey(&pk.k) 76 } 77 78 // Equals checks whether this key is equal to another 79 func (pk *RsaPublicKey) Equals(k Key) bool { 80 // make sure this is an rsa public key 81 other, ok := (k).(*RsaPublicKey) 82 if !ok { 83 return basicEquals(pk, k) 84 } 85 86 return pk.k.N.Cmp(other.k.N) == 0 && pk.k.E == other.k.E 87 } 88 89 // Sign returns a signature of the input data 90 func (sk *RsaPrivateKey) Sign(message []byte) ([]byte, error) { 91 hashed := sha256.Sum256(message) 92 return rsa.SignPKCS1v15(rand.Reader, &sk.sk, crypto.SHA256, hashed[:]) 93 } 94 95 // GetPublic returns a public key 96 func (sk *RsaPrivateKey) GetPublic() PubKey { 97 return &RsaPublicKey{k: sk.sk.PublicKey} 98 } 99 100 func (sk *RsaPrivateKey) Type() pb.KeyType { 101 return pb.KeyType_RSA 102 } 103 104 // Bytes returns protobuf bytes from a private key 105 func (sk *RsaPrivateKey) Bytes() ([]byte, error) { 106 return MarshalPrivateKey(sk) 107 } 108 109 func (sk *RsaPrivateKey) Raw() ([]byte, error) { 110 b := x509.MarshalPKCS1PrivateKey(&sk.sk) 111 return b, nil 112 } 113 114 // Equals checks whether this key is equal to another 115 func (sk *RsaPrivateKey) Equals(k Key) bool { 116 // make sure this is an rsa public key 117 other, ok := (k).(*RsaPrivateKey) 118 if !ok { 119 return basicEquals(sk, k) 120 } 121 a := sk.sk 122 b := other.sk 123 // Don't care about constant time. We're only comparing the public half. 124 return a.PublicKey.N.Cmp(b.PublicKey.N) == 0 && a.PublicKey.E == b.PublicKey.E 125 } 126 127 // UnmarshalRsaPrivateKey returns a private key from the input x509 bytes 128 func UnmarshalRsaPrivateKey(b []byte) (PrivKey, error) { 129 sk, err := x509.ParsePKCS1PrivateKey(b) 130 if err != nil { 131 return nil, err 132 } 133 if sk.N.BitLen() < MinRsaKeyBits { 134 return nil, ErrRsaKeyTooSmall 135 } 136 return &RsaPrivateKey{sk: *sk}, nil 137 } 138 139 // UnmarshalRsaPublicKey returns a public key from the input x509 bytes 140 func UnmarshalRsaPublicKey(b []byte) (PubKey, error) { 141 pub, err := x509.ParsePKIXPublicKey(b) 142 if err != nil { 143 return nil, err 144 } 145 pk, ok := pub.(*rsa.PublicKey) 146 if !ok { 147 return nil, errors.New("not actually an rsa public key") 148 } 149 if pk.N.BitLen() < MinRsaKeyBits { 150 return nil, ErrRsaKeyTooSmall 151 } 152 return &RsaPublicKey{k: *pk}, nil 153 }