Converting *crypto.PrivateKey to *rsa.PrivateKey

Issue

I am developing a method that will make a signature based in the type of private key that is passed as argument. To do that, I’m passing a *crypto.PrivateKey variable as argument. But the problem comes when I want to do a type assertion to use the argument.

func Sign(text string, privKey *crypto.PrivateKey) string{
if _, ok := (*privKey).(rsa.PrivateKey) //This is ok
if _, ok := (privKey).(*rsa.PrivateKey) //This is not ok 2

I guess I can do the first thing because if I use "*", the compiler think that it is an interface. But I don’t know why I can’t do the second thing, when it should be correct.

By the way, I need to use a variable of type *rsa.PrivateKey, I can do this this way:

privRsa, _ := (*privKey).(rsa.PrivateKey)
var priv *rsa.PrivateKey
priv = &privRsa

What I can not understand is why I can’t directly convert the *crypto.PrivateKey into *rsa.PrivateKey, or if it exist a way to do that. I thing doing it the way I’m doing it right now would allocate new space in memory that I shouldn’t if I want it to be efficient

Solution

crypto.PrivateKey is an interface. *crypto.PrivateKey is a pointer to an interface. You can use type-assertion on an interface to get the underlying value:

func Sign(text string, privKey crypto.PrivateKey) string{
   if _, ok := privKey.(rsa.PrivateKey) 
...
}

...
var pkey rsa.PrivateKey
Sign(text,pkey)

Here, the private key value in the interface is a copy of the rsa.PrivateKey.

If you pass the address of pkey, then, then the interface would have a pointer to the private key:

func Sign(text string, privKey crypto.PrivateKey) string{
   if _, ok := privKey.(*rsa.PrivateKey) 
...
}

...
var pkey rsa.PrivateKey
Sign(text,&pkey)

Answered By – Burak Serdar

Answer Checked By – Cary Denson (GoLangFix Admin)

Leave a Reply

Your email address will not be published.