Skip to content

Instantly share code, notes, and snippets.

@salrashid123
Created April 17, 2024 00:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save salrashid123/0e42a5761d02f2f9b6fd2e3d60fc864f to your computer and use it in GitHub Desktop.
Save salrashid123/0e42a5761d02f2f9b6fd2e3d60fc864f to your computer and use it in GitHub Desktop.
tink-golang sign/verify and extract rsa.PublicKey
package main
import (
"bytes"
"crypto"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/json"
"encoding/pem"
"log"
"math/big"
"github.com/tink-crypto/tink-go/v2/insecurecleartextkeyset"
"github.com/tink-crypto/tink-go/v2/keyset"
"github.com/tink-crypto/tink-go/v2/signature"
"google.golang.org/protobuf/proto"
commonpb "github.com/tink-crypto/tink-go/v2/proto/common_go_proto"
rsppb "github.com/tink-crypto/tink-go/v2/proto/rsa_ssa_pkcs1_go_proto"
tinkpb "github.com/tink-crypto/tink-go/v2/proto/tink_go_proto"
)
const ()
func bytesToBigInt(v []byte) *big.Int {
return new(big.Int).SetBytes(v)
}
func main() {
privateKeysetHandle, err := keyset.NewHandle(signature.RSA_SSA_PKCS1_3072_SHA256_F4_RAW_Key_Template())
if err != nil {
log.Fatal(err)
}
buf := new(bytes.Buffer)
w := keyset.NewJSONWriter(buf)
err = insecurecleartextkeyset.Write(privateKeysetHandle, w)
if err != nil {
log.Fatal(err)
}
var prettyJSON bytes.Buffer
err = json.Indent(&prettyJSON, buf.Bytes(), "", "\t")
if err != nil {
log.Fatalf("JSON parse error: %v ", err)
}
privateJSONKeyset := prettyJSON.String()
log.Printf("Private Keyset: %s\n", privateJSONKeyset)
publicKeysetHandle, err := privateKeysetHandle.Public()
if err != nil {
log.Fatalf("JSON parse error: %v ", err)
}
pubuf := new(bytes.Buffer)
pubw := keyset.NewJSONWriter(pubuf)
err = insecurecleartextkeyset.Write(publicKeysetHandle, pubw)
if err != nil {
log.Fatal(err)
}
var pubPrettyJSON bytes.Buffer
err = json.Indent(&pubPrettyJSON, pubuf.Bytes(), "", "\t")
if err != nil {
log.Fatalf("JSON parse error: %v ", err)
}
publicJSONKeyset := pubuf.String()
log.Printf("Public Keyset: %s\n", publicJSONKeyset)
// ***************
// Sign
signer, err := signature.NewSigner(privateKeysetHandle)
if err != nil {
log.Fatal(err)
}
data := []byte("data")
sig, err := signer.Sign(data)
if err != nil {
log.Fatal(err)
}
verifier, err := signature.NewVerifier(publicKeysetHandle)
if err != nil {
log.Fatal(err)
}
if err = verifier.Verify(sig, data); err != nil {
log.Fatal(err)
}
log.Println("sig is valid")
// ***
log.Println(publicKeysetHandle.KeysetInfo().GetKeyInfo()[0].TypeUrl)
bbw := new(bytes.Buffer)
bw := keyset.NewBinaryWriter(bbw)
err = publicKeysetHandle.WriteWithNoSecrets(bw)
if err != nil {
log.Fatalf("Could not write encrypted keyhandle %v", err)
}
tpb := &tinkpb.Keyset{}
err = proto.Unmarshal(bbw.Bytes(), tpb)
if err != nil {
log.Fatal(err)
}
for _, kk := range tpb.Key {
kserialized := kk.KeyData.Value
key := &rsppb.RsaSsaPkcs1PublicKey{}
if err := proto.Unmarshal(kserialized, key); err != nil {
log.Fatal(err)
}
pubKey := &rsa.PublicKey{
E: int(bytesToBigInt(key.GetE()).Int64()),
N: bytesToBigInt(key.GetN()),
}
pubkey_bytes, err := x509.MarshalPKIXPublicKey(pubKey)
if err != nil {
log.Fatalf("JSON parse error: %v ", err)
}
pubkey_pem := pem.EncodeToMemory(
&pem.Block{
Type: "RSA PUBLIC KEY",
Bytes: pubkey_bytes,
},
)
log.Printf("pubkey: \n%s\n", string(pubkey_pem))
if key.Params.HashType == commonpb.HashType_SHA256 {
digest := sha256.Sum256(data)
verifyErr := rsa.VerifyPKCS1v15(pubKey, crypto.SHA256, digest[:], sig)
if verifyErr != nil {
log.Printf("Verification failed: %s", verifyErr)
return
}
log.Println("verified..")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment