Created
June 26, 2022 15:46
-
-
Save salrashid123/fa092d083bac5ec2a0e9802e4b0c3071 to your computer and use it in GitHub Desktop.
Create or import new KMS TINK key for BigQuery SQL column-level encryption https://blog.salrashid.dev/articles/2022/bq_kms/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"encoding/base64" | |
"flag" | |
"fmt" | |
"math/rand" | |
"github.com/google/tink/go/aead" | |
"github.com/google/tink/go/aead/subtle" | |
"github.com/google/tink/go/keyset" | |
"github.com/google/tink/go/core/registry" | |
"github.com/google/tink/go/integration/gcpkms" | |
"github.com/golang/protobuf/proto" | |
gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto" | |
tinkpb "github.com/google/tink/go/proto/tink_go_proto" | |
) | |
var ( | |
keyURI = flag.String("keyURI", "", "KMS Key URI") | |
) | |
const () | |
func main() { | |
flag.Parse() | |
if *keyURI == "" { | |
fmt.Printf("--keyURI must be set") | |
return | |
} | |
gcpClient, err := gcpkms.NewClient("gcp-kms://") | |
if err != nil { | |
panic(err) | |
} | |
registry.RegisterKMSClient(gcpClient) | |
backend, err := gcpClient.GetAEAD(*keyURI) | |
if err != nil { | |
fmt.Printf("Could not acquire KMS AEAD %v\n", err) | |
return | |
} | |
secret := "8y/B?E(H+MbQeThVmYq3t6w9z$C&F)J@" | |
rawKey := []byte(secret) | |
id := rand.Uint32() | |
tk, err := subtle.NewAESGCM(rawKey) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
k := &gcmpb.AesGcmKey{ | |
Version: 0, | |
KeyValue: tk.Key, | |
} | |
fmt.Printf("Tink AESGCM Key: %v\n", base64.StdEncoding.EncodeToString(k.KeyValue)) | |
keyserialized, err := proto.Marshal(k) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
keysetKey := &tinkpb.Keyset_Key{ | |
KeyData: &tinkpb.KeyData{ | |
TypeUrl: "type.googleapis.com/google.crypto.tink.AesGcmKey", | |
KeyMaterialType: tinkpb.KeyData_SYMMETRIC, | |
Value: keyserialized, | |
}, | |
KeyId: id, | |
Status: tinkpb.KeyStatusType_ENABLED, | |
OutputPrefixType: tinkpb.OutputPrefixType_TINK, | |
} | |
ks := &tinkpb.Keyset{ | |
PrimaryKeyId: id, | |
Key: []*tinkpb.Keyset_Key{keysetKey}, | |
} | |
rawSerialized, err := proto.Marshal(ks) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
rd, err := backend.Encrypt(rawSerialized, []byte("")) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
ksi := &tinkpb.KeysetInfo{ | |
PrimaryKeyId: keysetKey.KeyId, | |
KeyInfo: []*tinkpb.KeysetInfo_KeyInfo{ | |
{ | |
TypeUrl: keysetKey.KeyData.TypeUrl, | |
Status: keysetKey.Status, | |
KeyId: keysetKey.KeyId, | |
OutputPrefixType: tinkpb.OutputPrefixType_TINK, | |
}, | |
}, | |
} | |
aeks := &tinkpb.EncryptedKeyset{ | |
EncryptedKeyset: rd, | |
KeysetInfo: ksi, | |
} | |
eksSerialized, err := proto.Marshal(aeks) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
r := keyset.NewBinaryReader(bytes.NewBuffer(eksSerialized)) | |
if err != nil { | |
fmt.Printf("Could not create TINK NewBinaryReader %v\n", err) | |
return | |
} | |
rk, err := r.ReadEncrypted() | |
if err != nil { | |
fmt.Printf("Could not create TINK keyHandle %v\n", err) | |
return | |
} | |
tv := base64.StdEncoding.EncodeToString(rk.EncryptedKeyset) | |
fmt.Printf(" Key %s\n", tv) | |
r = keyset.NewBinaryReader(bytes.NewBuffer(eksSerialized)) | |
if err != nil { | |
fmt.Printf(">>> Could not create TINK keyHandle %v\n", err) | |
return | |
} | |
kh, err := keyset.Read(r, backend) | |
if err != nil { | |
fmt.Printf("Could not create TINK keyHandle %v\n", err) | |
return | |
} | |
dkh, err := aead.New(kh) | |
if err != nil { | |
fmt.Printf("JSON parse error: %v \n", err) | |
return | |
} | |
ctaa, err := dkh.Encrypt([]byte("Juarez Gold DSS"), []byte("additional_data")) | |
if err != nil { | |
fmt.Printf("Error Encrypting %v\n", err) | |
return | |
} | |
fmt.Printf(" Cipher text: %s\n", base64.StdEncoding.EncodeToString(ctaa)) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment