github.com/emmansun/gmsm@v0.29.1/sm2/example_test.go (about)

     1  package sm2_test
     2  
     3  import (
     4  	"crypto/elliptic"
     5  	"crypto/rand"
     6  	"encoding/hex"
     7  	"errors"
     8  	"fmt"
     9  	"log"
    10  	"math/big"
    11  	"os"
    12  
    13  	"github.com/emmansun/gmsm/sm2"
    14  	"golang.org/x/crypto/cryptobyte"
    15  	"golang.org/x/crypto/cryptobyte/asn1"
    16  )
    17  
    18  func ExampleNewPrivateKey() {
    19  	keyBytes, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85")
    20  	priv, err := sm2.NewPrivateKey(keyBytes)
    21  	if err != nil {
    22  		log.Fatalf("fail to new private key %v", err)
    23  	}
    24  	fmt.Printf("%x\n", priv.D.Bytes())
    25  	// Output: 6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85
    26  }
    27  
    28  func ExampleNewPrivateKeyFromInt() {
    29  	key := big.NewInt(0x123456)
    30  	priv, err := sm2.NewPrivateKeyFromInt(key)
    31  	if err != nil {
    32  		log.Fatalf("fail to new private key %v", err)
    33  	}
    34  	fmt.Printf("%x\n", priv.D.Bytes())
    35  	// Output: 123456
    36  }
    37  
    38  func ExampleNewPublicKey() {
    39  	keypoints, _ := hex.DecodeString("048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1")
    40  	pub, err := sm2.NewPublicKey(keypoints)
    41  	if err != nil {
    42  		log.Fatalf("fail to new public key %v", err)
    43  	}
    44  	fmt.Printf("%x\n", elliptic.Marshal(sm2.P256(), pub.X, pub.Y))
    45  	// Output: 048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1
    46  }
    47  
    48  // This method provide a sample to handle ASN1 ciphertext ends with extra bytes.
    49  func Example_parseCipherASN1EndsWithInvalidBytes() {
    50  	// a sample method to get frist ASN1 SEQUENCE data
    51  	getFirstASN1Sequence := func(ciphertext []byte) ([]byte, []byte, error) {
    52  		input := cryptobyte.String(ciphertext)
    53  		var inner cryptobyte.String
    54  		if !input.ReadASN1(&inner, asn1.SEQUENCE) {
    55  			return nil, nil, errors.New("there are no sequence tag")
    56  		}
    57  		if len(input) == 0 {
    58  			return ciphertext, nil, nil
    59  		}
    60  		return ciphertext[:len(ciphertext)-len(input)], input, nil
    61  	}
    62  
    63  	ciphertext, _ := hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A")
    64  	_, rest, err := getFirstASN1Sequence(ciphertext)
    65  	if err != nil || len(rest) != 0 {
    66  		log.Fatalf("can't get a complete ASN1 sequence")
    67  	}
    68  
    69  	ciphertext, _ = hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A0000")
    70  	seq, rest, err := getFirstASN1Sequence(ciphertext)
    71  	if err != nil || len(rest) != 2 {
    72  		log.Fatalf("can't get a complete ASN1 sequence")
    73  	}
    74  
    75  	var (
    76  		x1, y1 = &big.Int{}, &big.Int{}
    77  		c2, c3 []byte
    78  		inner  cryptobyte.String
    79  	)
    80  
    81  	input := cryptobyte.String(seq)
    82  	if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
    83  		!input.Empty() ||
    84  		!inner.ReadASN1Integer(x1) ||
    85  		!inner.ReadASN1Integer(y1) ||
    86  		!inner.ReadASN1Bytes(&c3, asn1.OCTET_STRING) ||
    87  		!inner.ReadASN1Bytes(&c2, asn1.OCTET_STRING) ||
    88  		!inner.Empty() {
    89  		log.Fatalf("invalid cipher text")
    90  	}
    91  }
    92  
    93  // This is a reference method to force SM2 standard with SDK [crypto.Signer].
    94  func ExamplePrivateKey_Sign_forceSM2() {
    95  	toSign := []byte("ShangMi SM2 Sign Standard")
    96  	// real private key should be from secret storage
    97  	privKey, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85")
    98  	testkey, err := sm2.NewPrivateKey(privKey)
    99  	if err != nil {
   100  		log.Fatalf("fail to new private key %v", err)
   101  	}
   102  
   103  	// force SM2 sign standard and use default UID
   104  	sig, err := testkey.Sign(rand.Reader, toSign, sm2.DefaultSM2SignerOpts)
   105  	if err != nil {
   106  		fmt.Fprintf(os.Stderr, "Error from sign: %s\n", err)
   107  		return
   108  	}
   109  
   110  	// Since sign is a randomized function, signature will be
   111  	// different each time.
   112  	fmt.Printf("%x\n", sig)
   113  }
   114  
   115  func ExampleVerifyASN1WithSM2() {
   116  	// real public key should be from cert or public key pem file
   117  	keypoints, _ := hex.DecodeString("048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1")
   118  	testkey, err := sm2.NewPublicKey(keypoints)
   119  	if err != nil {
   120  		log.Fatalf("fail to new public key %v", err)
   121  	}
   122  
   123  	toSign := []byte("ShangMi SM2 Sign Standard")
   124  	signature, _ := hex.DecodeString("304402205b3a799bd94c9063120d7286769220af6b0fa127009af3e873c0e8742edc5f890220097968a4c8b040fd548d1456b33f470cabd8456bfea53e8a828f92f6d4bdcd77")
   125  
   126  	ok := sm2.VerifyASN1WithSM2(testkey, nil, toSign, signature)
   127  
   128  	fmt.Printf("%v\n", ok)
   129  	// Output: true
   130  }
   131  
   132  func ExampleEncryptASN1() {
   133  	// real public key should be from cert or public key pem file
   134  	keypoints, _ := hex.DecodeString("048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1")
   135  	testkey, err := sm2.NewPublicKey(keypoints)
   136  	if err != nil {
   137  		log.Fatalf("fail to new public key %v", err)
   138  	}
   139  
   140  	secretMessage := []byte("send reinforcements, we're going to advance")
   141  
   142  	// crypto/rand.Reader is a good source of entropy for randomizing the
   143  	// encryption function.
   144  	rng := rand.Reader
   145  
   146  	ciphertext, err := sm2.EncryptASN1(rng, testkey, secretMessage)
   147  	if err != nil {
   148  		fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err)
   149  		return
   150  	}
   151  	// Since encryption is a randomized function, ciphertext will be
   152  	// different each time.
   153  	fmt.Printf("Ciphertext: %x\n", ciphertext)
   154  }
   155  
   156  func ExamplePrivateKey_Decrypt() {
   157  	ciphertext, _ := hex.DecodeString("308194022100bd31001ce8d39a4a0119ff96d71334cd12d8b75bbc780f5bfc6e1efab535e85a02201839c075ff8bf761dcbe185c9750816410517001d6a130f6ab97fb23337cce150420ea82bd58d6a5394eb468a769ab48b6a26870ca075377eb06663780c920ea5ee0042be22abcf48e56ae9d29ac770d9de0d6b7094a874a2f8d26c26e0b1daaf4ff50a484b88163d04785b04585bb")
   158  
   159  	// real private key should be from secret storage
   160  	privKey, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85")
   161  	testkey, err := sm2.NewPrivateKey(privKey)
   162  	if err != nil {
   163  		log.Fatalf("fail to new private key %v", err)
   164  	}
   165  
   166  	plaintext, err := testkey.Decrypt(nil, ciphertext, nil)
   167  	if err != nil {
   168  		fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err)
   169  		return
   170  	}
   171  
   172  	fmt.Printf("Plaintext: %s\n", string(plaintext))
   173  	// Output: Plaintext: send reinforcements, we're going to advance
   174  }