Secp256k1 Public key generated with Azure Key Vault is of 43 characters - go

I am using Azure key vault for a pet project and I am creating Secp256k1 key pair. Steps to create the key in Azure:
Open your Key Vault resource
Choose Keys from the left side panel.
Click Generate/Import from the top left corner.
Chose Key Type: EC, EC name: P-256K (Secp256k1 basically)
Click Create.
Once I try to access the Public part of the key from my Go-lang app using below code:
func main(){
authorizer, err := kvauth.NewAuthorizerFromEnvironment()
if err != nil {
fmt.Printf("unable to create vault authorizer: %v\n", err)
os.Exit(1)
}
basicClient := keyvault.New()
basicClient.Authorizer = authorizer
getKey(basicClient, KeyName)
}
func getKey(basicClient keyvault.BaseClient, keyname string) {
keyResp, err := basicClient.GetKey(context.Background(), "https://"+vaultName+".vault.azure.net", keyname, "")
if err != nil {
fmt.Printf("unable to get value for key: %v\n", err)
os.Exit(1)
}
fmt.Println("X = ",*keyResp.Key.X)
fmt.Println("Y = ",*keyResp.Key.Y)
}
You can look at the different attributes of the Key listed here at Mircosoft Docs.
https://learn.microsoft.com/en-us/rest/api/keyvault/create-key/create-key#request-body
Above code gives me an output as:
X = uAv6rXZedQbihGUQwFkEZl35LeI7OHdhHSOEf3VpXyw
Y = Q8MzSQGOtqT41lsYU-P82o6Fryn8Vnub0l0kdOOdOHI
The given keys are 43 chars in length, while I understand by reading about Secp256k1 that these are 32 chars only. The key size being 43 is giving me an error in the application I intend to use it at.
Am I missing something here or Azure gives some extra characters or something like that?
Any help appreciated.

Related

How to use key pair generated by openpgp in go

I'm trying to generate keypair with openpgp lib and when I want to test it by encrypting a test string, it returns the following error openpgp: invalid argument: cannot encrypt because no candidate hash functions are compiled in. (Wanted RIPEMD160 in this case.). However it works when I pass a public key exported from gpg.
Also I'm wondering how to encrypt the private key like gpg --generate-key does?
func main() {
var e *openpgp.Entity
var pubKey *bytes.Buffer
e, _ = openpgp.NewEntity("testUser", "test", "test#test.test", nil)
for _, id := range e.Identities {
err := id.SelfSignature.SignUserId(id.UserId.Id, e.PrimaryKey, e.PrivateKey, nil)
if err != nil {
fmt.Println(err)
return
}
}
buf := new(bytes.Buffer)
w, err := armor.Encode(buf, openpgp.PublicKeyType, nil)
if err != nil {
fmt.Println(err)
return
}
e.Serialize(w)
w.Close()
pubKey = buf
// Encrypting test with public key
entity, err := openpgp.ReadArmoredKeyRing(pubKey)
if err != nil {
fmt.Println(err)
return
}
buf = new(bytes.Buffer)
encoderWriter, err := armor.Encode(buf, "PGP MESSAGE", make(map[string]string))
if err != nil {
fmt.Println(err)
return
}
encryptorWriter, err := openpgp.Encrypt(encoderWriter, entity, nil, nil, nil)
if err != nil {
fmt.Println(err)
return
}
encryptorWriter.Write([]byte("hello world"))
encryptorWriter.Close()
encoderWriter.Close()
fmt.Println(buf.String())
}
I had the exact same error.
TL; DR
It seems that it's an abandoned bug of the golang.org/x/crypto/openpgp package.
golang.org/x/crypto/openpgp package is frozen and deprecated. (= wontfix)
Use a patched fork package instead.
github.com/ProtonMail/go-crypto package # GitHub
TS; DR
Since the official "golang.org/x/crypto/openpgp" package was frozen and deprecated, as long as we use the "golang.org/x/crypto/openpgp" package, it seems that the only current workaround is to either;
Downgrade the Go version and the package, then blank import "_ golang.org/x/crypto/ripemd160" as #mh-cbon mentioned.
Patch the rejected PR on your own. (Rejected due to the freezing of x/crypto/openpgp package)
Patch: https://github.com/golang/crypto/pull/128/files
PR: Use correct default hashes and default ciphers when no preferences given
But I had to implement an OpenPGP key pair generator on Go 1.16.6. Don't ask why...
So, my current alternative was to use the forked package. Which was one of the abounding forks that the Go team mentioned as a sample.
github.com/ProtonMail/go-crypto package # GitHub
go get github.com/ProtonMail/go-crypto
Remove golang.org/x/crypto/openpgp from go.mod
Replace all the "golang.org/x/crypto/openpgp" to "github.com/ProtonMail/go-crypto/openpgp" in the source code.
go mod tidy
References
"x/crypto/openpgp: mark as frozen and deprecated" | Issue #44226 | go | golang # GitHub
"x/crypto/openpgp: new entities cannot be encrypted to by default" | Issue #37646 | go | golang # GitHub
"x/crypto/openpgp: new entities cannot be encrypted to by default" | Issue #12153 | go | golang # GitHub

How to Decode composite custom extensions in x509 certificate in golang? With current code Error is : asn1: structure error: sequence tag mismatch

I am writing golang code to parse an X509 Certificate with custom extensions:
The code is following:
func (e *PckCert) ParseValue() error {
var ext pkix.Extension
var err error
for i := 0; i < len(e.PckCertObj.Extensions); i++ {
ext = e.PckCertObj.Extensions[i]
if ExtxOid.Equal(ext.Id) == true { ///ExtOid is a constant OId is known
var asn1Extensions []asn1.RawValue
_, err := asn1.Unmarshal(ext.Value, &asn1Extensions)
if err != nil {
log.Info("err: ", err)
return errors.Wrap(err, "Asn1 Extension Unmarshal failed")
}
var sExtension pkix.Extension ///For normal OIDs
var sExtensions1 []pkix.Extension /// For TC1 SVN OID extensions under extension
for j := 0; j < len(asn1Extensions); j++ {
_, err = asn1.Unmarshal(asn1Extensions[j].FullBytes, &sExtension)
if err != nil {
log.Info("err came: ", err)
log.Info("Warning: Asn1 Extension Unmarshal failed - 2 for index:", j)
_, err = asn1.Unmarshal(asn1Extensions[j].FullBytes, &sExtensions1)
if err != nil {
log.Info("err came 2: ", err) ///**for extensions within extensions here code is failing with error: sequence tag mismatch**
}
}
}
}
}
}
The above code is failing only for composite extensions sequence TC OID. For composite extensions sequence I am getting "asn1: structure error: sequence tag mismatch". Please help in this..I am able to unmarshal all rest of it except composite extension TC OID
Basically, you need to distinguish between a regular extension and a collection. If an OID is a collection, you need to pass in slice of type []asn1.RawValue just like you are parsing e.PckCertObj.Extensions[i] in the above code.
So, how do you know if have extension with a value or a collection. You need to extract the Object Identified (OID) from asn byte stream as follows
var oid asn1.ObjectIdentifier
rest, _ := asn1.Ummarshal(bytes, &oid)
You can then compare against a particular OID
if oid.Equal(knownCollectionOID) {
var collExts []asn1.RawValue
asn1.Unmarshal(rest, &collExts)
for _, ext := range collExts {
fmt.Println("Do something with the extension")
}
}

PGP file decryption\

I am looking for suggestions on how to use openPGP to decrypt a PGP encrypted file we receive externally. The file is placed on a Google Cloud bucket and I am planning to use a Cloud function to run the decryption.
There are several examples (this and this) on the web with Go and OpenPGP but they are limited to decrypting strings/texts and not files. The file is encrypted using a traditional PGP encrypt command.
I am trying to avoid creating a VM or asking the external agency to change the encryption process.
In your example linked you can see that it decrypts a byte slice []byte. It can be the content from an encrypted file.
You can replace the
decrypted, err := pgp.Decrypt(privEntity, encrypted)
if err != nil {
t.Error(err)
}
by
encrypted, err := ioutil.ReadFile(filename)
if err != nil {
t.Error(err)
}
decrypted, err := pgp.Decrypt(privEntity, encrypted)
if err != nil {
t.Error(err)
}

Go - How to Generate an SSH PublicKey Fingerprint from PublicKey, the PublicKey's type maybe is one of [ rsa dsa ssh-rsa ssh-dss ecdsa ]

I only have a PublicKey string, How do I get the PublicKey Fingerprint?
I have got some idea form https://go-review.googlesource.com/c/crypto/+/32814, but I do not know how to
implement ssh.PublicKey interface.
You probably want to use ssh.ParseAuthorizedKey from the ssh package to load the key:
https://godoc.org/golang.org/x/crypto/ssh#ParseAuthorizedKey
That will give you a public key which you can call ssh.FingerprintLegacyMD5 on in order to get the fingerprint (assuming here you want the md5).
https://godoc.org/golang.org/x/crypto/ssh#FingerprintLegacyMD5
https://godoc.org/golang.org/x/crypto/ssh#FingerprintSHA256
func main() {
// Read a key from a file in authorized keys file line format
// This could be an rsa.pub file or a line from authorized_keys
pubKeyBytes := []byte(`ssh-rsa AAAABMYKEY...ABC me#myplace.local`)
// Parse the key, other info ignored
pk, _, _, _, err := ssh.ParseAuthorizedKey(pubKeyBytes)
if err != nil {
panic(err)
}
// Get the fingerprint
f := ssh.FingerprintLegacyMD5(pk)
// Print the fingerprint
fmt.Printf("%s\n", f)
}
There are two fingerprint functions provided, not sure which one you need.

Go-Redis HMSet with string fields gives WRONGTYPE Operation

I'm trying to use HMSET to set a new hash containing two string fields, id and content.
I'm able to make this via redis-cli pretty easily using SET i 0 to initialize a counter for ids, then creating a new hash using HMSET test id hey content herro and getting both of these fields with HMGET test id content resulting in 1) hey 2) herro.
Unfortunately I'm not able to achieve such result with Go-Redis and in particular with HMSet.
So far I tried
var uid = "0"
err = c.Get("i").Err()
if(err != nil) {
//If the counter is not set, set it to 0
err := c.Set("i", "0", 0).Err()
if(err != nil){
panic(err)
}
} else {
//Else, increment it
counter, err := c.Incr("i").Result()
//Cast it to string
uid = strconv.FormatInt(index, 10)
if(err != nil){
panic(err)
}
//Set new counter
err = c.Set("i", counter, 0).Err()
if( err!= nil ){
panic(err)
}
}
//Init a map[string]interface{}
var m = make(map[string]interface{})
m["id"] = uid
m["content"] = "herro"
hash, err := c.HMSet("i", m).Result()
if(err != nil){
panic(err)
}
fmt.Println(hash)
Everything works fine but c.HMSet("i", m).Result(). I get:
WRONGTYPE Operation against a key holding the wrong kind of value
And I cannot really get why since I managed to make it work on the very same way in redis-cli.
HMSet is defined as func (c *Client) HMSet(key string, fields map[string]interface{}) *StatusCmd.
I wasn't able to find any example online using Go-Redis illustrating this use case.
What Am I doing Wrong?
You are accessing the same key "i" twice - once as a string when calling SET, and then as a hash when calling HMSET.
The error you are getting is just redis denying HMSET on a string, which is an invalid operation.
BTW the other way around will work - calling SET on any type in redis will just write a string instead of that value, so be careful.

Resources