github.com/polarismesh/polaris@v1.17.8/common/rsa/rsa.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  package rsa
    19  
    20  import (
    21  	"bytes"
    22  	"crypto/rand"
    23  	"crypto/rsa"
    24  	"crypto/x509"
    25  	"encoding/base64"
    26  )
    27  
    28  // RSAKey RSA key pair
    29  type RSAKey struct {
    30  	PrivateKey string
    31  	PublicKey  string
    32  }
    33  
    34  // GenerateKey generate RSA key pair
    35  func GenerateRSAKey() (*RSAKey, error) {
    36  	privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	rsaKey := &RSAKey{
    41  		PrivateKey: base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PrivateKey(privateKey)),
    42  		PublicKey:  base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)),
    43  	}
    44  	return rsaKey, nil
    45  }
    46  
    47  // Encrypt RSA encrypt plaintext using public key
    48  func Encrypt(plaintext, publicKey []byte) ([]byte, error) {
    49  	pub, err := x509.ParsePKCS1PublicKey(publicKey)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  	totalLen := len(plaintext)
    54  	segLen := pub.Size() - 11
    55  	start := 0
    56  	buffer := bytes.Buffer{}
    57  	for start < totalLen {
    58  		end := start + segLen
    59  		if end > totalLen {
    60  			end = totalLen
    61  		}
    62  		seg, err := rsa.EncryptPKCS1v15(rand.Reader, pub, plaintext[start:end])
    63  		if err != nil {
    64  			return nil, err
    65  		}
    66  		buffer.Write(seg)
    67  		start = end
    68  	}
    69  	return buffer.Bytes(), nil
    70  }
    71  
    72  // Decrypt RSA decrypt ciphertext using private key
    73  func Decrypt(ciphertext, privateKey []byte) ([]byte, error) {
    74  	priv, err := x509.ParsePKCS1PrivateKey(privateKey)
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  	keySize := priv.Size()
    79  	totalLen := len(ciphertext)
    80  	start := 0
    81  	buffer := bytes.Buffer{}
    82  	for start < totalLen {
    83  		end := start + keySize
    84  		if end > totalLen {
    85  			end = totalLen
    86  		}
    87  		seg, err := rsa.DecryptPKCS1v15(rand.Reader, priv, ciphertext[start:end])
    88  		if err != nil {
    89  			return nil, err
    90  		}
    91  		buffer.Write(seg)
    92  		start = end
    93  	}
    94  	return buffer.Bytes(), nil
    95  }
    96  
    97  // EncryptToBase64 RSA encrypt plaintext and base64 encode ciphertext
    98  func EncryptToBase64(plaintext []byte, base64PublicKey string) (string, error) {
    99  	pub, err := base64.StdEncoding.DecodeString(base64PublicKey)
   100  	if err != nil {
   101  		return "", err
   102  	}
   103  	ciphertext, err := Encrypt(plaintext, pub)
   104  	if err != nil {
   105  		return "", err
   106  	}
   107  	return base64.StdEncoding.EncodeToString(ciphertext), nil
   108  }
   109  
   110  // DecryptFromBase64 base64 decode ciphertext and RSA decrypt
   111  func DecryptFromBase64(base64Ciphertext, base64PrivateKey string) ([]byte, error) {
   112  	priv, err := base64.StdEncoding.DecodeString(base64PrivateKey)
   113  	if err != nil {
   114  		return nil, err
   115  	}
   116  	ciphertext, err := base64.StdEncoding.DecodeString(base64Ciphertext)
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  	return Decrypt(ciphertext, priv)
   121  }