github.com/aacfactory/fns@v1.2.86-0.20240310083819-80d667fc0a17/commons/signatures/rsa.go (about)

     1  /*
     2   * Copyright 2023 Wang Min Xiang
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   * 	http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   *
    16   */
    17  
    18  package signatures
    19  
    20  import (
    21  	"crypto"
    22  	"crypto/rand"
    23  	"crypto/rsa"
    24  	"crypto/sha256"
    25  	"crypto/x509"
    26  	"encoding/pem"
    27  	"github.com/aacfactory/errors"
    28  	"hash"
    29  	"sync"
    30  )
    31  
    32  func RSA(keyPEM []byte) (Signature, error) {
    33  	block, _ := pem.Decode(keyPEM)
    34  	privateKey, priErr := x509.ParsePKCS8PrivateKey(block.Bytes)
    35  	if priErr != nil {
    36  		return nil, errors.Warning("fns: create rsa signer failed").WithCause(errors.Warning("parse private key failed")).WithCause(priErr)
    37  	}
    38  	key, ok := privateKey.(*rsa.PrivateKey)
    39  	if !ok {
    40  		return nil, errors.Warning("fns: create rsa signer failed").WithCause(errors.Warning("private is not rsa"))
    41  	}
    42  	return &rsaSigner{
    43  		pub: &key.PublicKey,
    44  		pri: key,
    45  		pool: sync.Pool{
    46  			New: func() any {
    47  				return sha256.New()
    48  			},
    49  		},
    50  	}, nil
    51  }
    52  
    53  type rsaSigner struct {
    54  	pub  *rsa.PublicKey
    55  	pri  *rsa.PrivateKey
    56  	pool sync.Pool
    57  }
    58  
    59  func (s *rsaSigner) acquire() (h hash.Hash) {
    60  	v := s.pool.Get()
    61  	if v != nil {
    62  		h = v.(hash.Hash)
    63  		return
    64  	}
    65  	h = sha256.New()
    66  	return
    67  }
    68  
    69  func (s *rsaSigner) release(h hash.Hash) {
    70  	h.Reset()
    71  	s.pool.Put(h)
    72  	return
    73  }
    74  
    75  func (s *rsaSigner) Sign(target []byte) (signature []byte) {
    76  	h := s.acquire()
    77  	h.Write(target)
    78  	hashed := h.Sum(nil)
    79  	signature, _ = rsa.SignPKCS1v15(rand.Reader, s.pri, crypto.SHA256, hashed)
    80  	s.release(h)
    81  	return
    82  }
    83  
    84  func (s *rsaSigner) Verify(target []byte, signature []byte) (ok bool) {
    85  	h := s.acquire()
    86  	h.Write(target)
    87  	hashed := h.Sum(nil)
    88  	ok = rsa.VerifyPKCS1v15(s.pub, crypto.SHA256, hashed, signature) == nil
    89  	s.release(h)
    90  	return
    91  }