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 mac_test 18*e7b1675dSTing-Kang Chang 19*e7b1675dSTing-Kang Chang// [START mac-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/mac" 29*e7b1675dSTing-Kang Chang) 30*e7b1675dSTing-Kang Chang 31*e7b1675dSTing-Kang Changfunc Example() { 32*e7b1675dSTing-Kang Chang // A keyset created with "tinkey create-keyset --key-template=HMAC_SHA256_128BITTAG". 33*e7b1675dSTing-Kang Chang // Note that this keyset has the secret key information in cleartext. 34*e7b1675dSTing-Kang Chang jsonKeyset := `{ 35*e7b1675dSTing-Kang Chang "key": [{ 36*e7b1675dSTing-Kang Chang "keyData": { 37*e7b1675dSTing-Kang Chang "keyMaterialType": 38*e7b1675dSTing-Kang Chang "SYMMETRIC", 39*e7b1675dSTing-Kang Chang "typeUrl": 40*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.HmacKey", 41*e7b1675dSTing-Kang Chang "value": 42*e7b1675dSTing-Kang Chang "EgQIAxAQGiA0LQjovcydWhVQV3k8W9ZSRkd7Ei4Y/TRWApE8guwV4Q==" 43*e7b1675dSTing-Kang Chang }, 44*e7b1675dSTing-Kang Chang "keyId": 1892702217, 45*e7b1675dSTing-Kang Chang "outputPrefixType": "TINK", 46*e7b1675dSTing-Kang Chang "status": "ENABLED" 47*e7b1675dSTing-Kang Chang }], 48*e7b1675dSTing-Kang Chang "primaryKeyId": 1892702217 49*e7b1675dSTing-Kang Chang }` 50*e7b1675dSTing-Kang Chang 51*e7b1675dSTing-Kang Chang // Create a keyset handle from the cleartext keyset in the previous 52*e7b1675dSTing-Kang Chang // step. The keyset handle provides abstract access to the underlying keyset to 53*e7b1675dSTing-Kang Chang // limit the exposure of accessing the raw key material. WARNING: In practice, 54*e7b1675dSTing-Kang Chang // it is unlikely you will want to use a insecurecleartextkeyset, as it implies 55*e7b1675dSTing-Kang Chang // that your key material is passed in cleartext, which is a security risk. 56*e7b1675dSTing-Kang Chang // Consider encrypting it with a remote key in Cloud KMS, AWS KMS or HashiCorp Vault. 57*e7b1675dSTing-Kang Chang // See https://github.com/google/tink/blob/master/docs/GOLANG-HOWTO.md#storing-and-loading-existing-keysets. 58*e7b1675dSTing-Kang Chang keysetHandle, err := insecurecleartextkeyset.Read( 59*e7b1675dSTing-Kang Chang keyset.NewJSONReader(bytes.NewBufferString(jsonKeyset))) 60*e7b1675dSTing-Kang Chang if err != nil { 61*e7b1675dSTing-Kang Chang log.Fatal(err) 62*e7b1675dSTing-Kang Chang } 63*e7b1675dSTing-Kang Chang 64*e7b1675dSTing-Kang Chang // Retrieve the MAC primitive we want to use from the keyset handle. 65*e7b1675dSTing-Kang Chang primitive, err := mac.New(keysetHandle) 66*e7b1675dSTing-Kang Chang if err != nil { 67*e7b1675dSTing-Kang Chang log.Fatal(err) 68*e7b1675dSTing-Kang Chang } 69*e7b1675dSTing-Kang Chang 70*e7b1675dSTing-Kang Chang // Use the primitive to create a MAC tag for some data. In this case the primary 71*e7b1675dSTing-Kang Chang // key of the keyset will be used (which is also the only key in this example). 72*e7b1675dSTing-Kang Chang data := []byte("data") 73*e7b1675dSTing-Kang Chang tag, err := primitive.ComputeMAC(data) 74*e7b1675dSTing-Kang Chang if err != nil { 75*e7b1675dSTing-Kang Chang log.Fatal(err) 76*e7b1675dSTing-Kang Chang } 77*e7b1675dSTing-Kang Chang 78*e7b1675dSTing-Kang Chang // Use the primitive to verify the tag. VerifyMAC finds the correct key in 79*e7b1675dSTing-Kang Chang // the keyset. If no key is found or verification fails, it returns an error. 80*e7b1675dSTing-Kang Chang err = primitive.VerifyMAC(tag, data) 81*e7b1675dSTing-Kang Chang if err != nil { 82*e7b1675dSTing-Kang Chang log.Fatal(err) 83*e7b1675dSTing-Kang Chang } 84*e7b1675dSTing-Kang Chang fmt.Printf("tag is valid") 85*e7b1675dSTing-Kang Chang // Output: tag is valid 86*e7b1675dSTing-Kang Chang} 87*e7b1675dSTing-Kang Chang 88*e7b1675dSTing-Kang Chang// [END mac-example] 89