1*e7b1675dSTing-Kang Chang// Copyright 2019 Google LLC 2*e7b1675dSTing-Kang Chang// 3*e7b1675dSTing-Kang Chang// Licensed under the Apache License, Version 2.0 (the "License"); 4*e7b1675dSTing-Kang Chang// you may not use this file except in compliance with the License. 5*e7b1675dSTing-Kang Chang// You may obtain a copy of the License at 6*e7b1675dSTing-Kang Chang// 7*e7b1675dSTing-Kang Chang// http://www.apache.org/licenses/LICENSE-2.0 8*e7b1675dSTing-Kang Chang// 9*e7b1675dSTing-Kang Chang// Unless required by applicable law or agreed to in writing, software 10*e7b1675dSTing-Kang Chang// distributed under the License is distributed on an "AS IS" BASIS, 11*e7b1675dSTing-Kang Chang// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*e7b1675dSTing-Kang Chang// See the License for the specific language governing permissions and 13*e7b1675dSTing-Kang Chang// limitations under the License. 14*e7b1675dSTing-Kang Chang// 15*e7b1675dSTing-Kang Chang//////////////////////////////////////////////////////////////////////////////// 16*e7b1675dSTing-Kang Chang 17*e7b1675dSTing-Kang Changpackage signature_test 18*e7b1675dSTing-Kang Chang 19*e7b1675dSTing-Kang Chang// [START signature-example] 20*e7b1675dSTing-Kang Chang 21*e7b1675dSTing-Kang Changimport ( 22*e7b1675dSTing-Kang Chang "bytes" 23*e7b1675dSTing-Kang Chang "fmt" 24*e7b1675dSTing-Kang Chang "log" 25*e7b1675dSTing-Kang Chang 26*e7b1675dSTing-Kang Chang "github.com/google/tink/go/insecurecleartextkeyset" 27*e7b1675dSTing-Kang Chang "github.com/google/tink/go/keyset" 28*e7b1675dSTing-Kang Chang "github.com/google/tink/go/signature" 29*e7b1675dSTing-Kang Chang) 30*e7b1675dSTing-Kang Chang 31*e7b1675dSTing-Kang Changfunc Example() { 32*e7b1675dSTing-Kang Chang // A private keyset created with 33*e7b1675dSTing-Kang Chang // "tinkey create-keyset --key-template=ECDSA_P256 --out private_keyset.cfg". 34*e7b1675dSTing-Kang Chang // Note that this keyset has the secret key information in cleartext. 35*e7b1675dSTing-Kang Chang privateJSONKeyset := `{ 36*e7b1675dSTing-Kang Chang "key": [{ 37*e7b1675dSTing-Kang Chang "keyData": { 38*e7b1675dSTing-Kang Chang "keyMaterialType": 39*e7b1675dSTing-Kang Chang "ASYMMETRIC_PRIVATE", 40*e7b1675dSTing-Kang Chang "typeUrl": 41*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.EcdsaPrivateKey", 42*e7b1675dSTing-Kang Chang "value": 43*e7b1675dSTing-Kang Chang "EkwSBggDEAIYAhogEiSZ9u2nDtvZuDgWgGsVTIZ5/V08N4ycUspTX0RYRrkiIHpEwHxQd1bImkyMvV2bqtUbgMh5uPSTdnUEGrPXdt56GiEA3iUi+CRN71qy0fOCK66xAW/IvFyjOGtxjppRhSFUneo=" 44*e7b1675dSTing-Kang Chang }, 45*e7b1675dSTing-Kang Chang "keyId": 611814836, 46*e7b1675dSTing-Kang Chang "outputPrefixType": "TINK", 47*e7b1675dSTing-Kang Chang "status": "ENABLED" 48*e7b1675dSTing-Kang Chang }], 49*e7b1675dSTing-Kang Chang "primaryKeyId": 611814836 50*e7b1675dSTing-Kang Chang }` 51*e7b1675dSTing-Kang Chang 52*e7b1675dSTing-Kang Chang // The corresponding public keyset created with 53*e7b1675dSTing-Kang Chang // "tinkey create-public-keyset --in private_keyset.cfg" 54*e7b1675dSTing-Kang Chang publicJSONKeyset := `{ 55*e7b1675dSTing-Kang Chang "key": [{ 56*e7b1675dSTing-Kang Chang "keyData": { 57*e7b1675dSTing-Kang Chang "keyMaterialType": 58*e7b1675dSTing-Kang Chang "ASYMMETRIC_PUBLIC", 59*e7b1675dSTing-Kang Chang "typeUrl": 60*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.EcdsaPublicKey", 61*e7b1675dSTing-Kang Chang "value": 62*e7b1675dSTing-Kang Chang "EgYIAxACGAIaIBIkmfbtpw7b2bg4FoBrFUyGef1dPDeMnFLKU19EWEa5IiB6RMB8UHdWyJpMjL1dm6rVG4DIebj0k3Z1BBqz13beeg==" 63*e7b1675dSTing-Kang Chang }, 64*e7b1675dSTing-Kang Chang "keyId": 611814836, 65*e7b1675dSTing-Kang Chang "outputPrefixType": "TINK", 66*e7b1675dSTing-Kang Chang "status": "ENABLED" 67*e7b1675dSTing-Kang Chang }], 68*e7b1675dSTing-Kang Chang "primaryKeyId": 611814836 69*e7b1675dSTing-Kang Chang }` 70*e7b1675dSTing-Kang Chang 71*e7b1675dSTing-Kang Chang // Create a keyset handle from the cleartext private keyset in the previous 72*e7b1675dSTing-Kang Chang // step. The keyset handle provides abstract access to the underlying keyset to 73*e7b1675dSTing-Kang Chang // limit the access of the raw key material. WARNING: In practice, 74*e7b1675dSTing-Kang Chang // it is unlikely you will want to use a insecurecleartextkeyset, as it implies 75*e7b1675dSTing-Kang Chang // that your key material is passed in cleartext, which is a security risk. 76*e7b1675dSTing-Kang Chang // Consider encrypting it with a remote key in Cloud KMS, AWS KMS or HashiCorp Vault. 77*e7b1675dSTing-Kang Chang // See https://github.com/google/tink/blob/master/docs/GOLANG-HOWTO.md#storing-and-loading-existing-keysets. 78*e7b1675dSTing-Kang Chang privateKeysetHandle, err := insecurecleartextkeyset.Read( 79*e7b1675dSTing-Kang Chang keyset.NewJSONReader(bytes.NewBufferString(privateJSONKeyset))) 80*e7b1675dSTing-Kang Chang if err != nil { 81*e7b1675dSTing-Kang Chang log.Fatal(err) 82*e7b1675dSTing-Kang Chang } 83*e7b1675dSTing-Kang Chang 84*e7b1675dSTing-Kang Chang // Retrieve the Signer primitive from privateKeysetHandle. 85*e7b1675dSTing-Kang Chang signer, err := signature.NewSigner(privateKeysetHandle) 86*e7b1675dSTing-Kang Chang if err != nil { 87*e7b1675dSTing-Kang Chang log.Fatal(err) 88*e7b1675dSTing-Kang Chang } 89*e7b1675dSTing-Kang Chang 90*e7b1675dSTing-Kang Chang // Use the primitive to sign a message. In this case, the primary key of the 91*e7b1675dSTing-Kang Chang // keyset will be used (which is also the only key in this example). 92*e7b1675dSTing-Kang Chang data := []byte("data") 93*e7b1675dSTing-Kang Chang sig, err := signer.Sign(data) 94*e7b1675dSTing-Kang Chang if err != nil { 95*e7b1675dSTing-Kang Chang log.Fatal(err) 96*e7b1675dSTing-Kang Chang } 97*e7b1675dSTing-Kang Chang 98*e7b1675dSTing-Kang Chang // Create a keyset handle from the keyset containing the public key. Because the 99*e7b1675dSTing-Kang Chang // public keyset does not contain any secrets, we can use [keyset.ReadWithNoSecrets]. 100*e7b1675dSTing-Kang Chang publicKeysetHandle, err := keyset.ReadWithNoSecrets( 101*e7b1675dSTing-Kang Chang keyset.NewJSONReader(bytes.NewBufferString(publicJSONKeyset))) 102*e7b1675dSTing-Kang Chang if err != nil { 103*e7b1675dSTing-Kang Chang log.Fatal(err) 104*e7b1675dSTing-Kang Chang } 105*e7b1675dSTing-Kang Chang 106*e7b1675dSTing-Kang Chang // Retrieve the Verifier primitive from publicKeysetHandle. 107*e7b1675dSTing-Kang Chang verifier, err := signature.NewVerifier(publicKeysetHandle) 108*e7b1675dSTing-Kang Chang if err != nil { 109*e7b1675dSTing-Kang Chang log.Fatal(err) 110*e7b1675dSTing-Kang Chang } 111*e7b1675dSTing-Kang Chang 112*e7b1675dSTing-Kang Chang if err = verifier.Verify(sig, data); err != nil { 113*e7b1675dSTing-Kang Chang log.Fatal(err) 114*e7b1675dSTing-Kang Chang } 115*e7b1675dSTing-Kang Chang fmt.Printf("sig is valid") 116*e7b1675dSTing-Kang Chang // Output: sig is valid 117*e7b1675dSTing-Kang Chang} 118*e7b1675dSTing-Kang Chang 119*e7b1675dSTing-Kang Chang// [END signature-example] 120