How to validate a signature signed with PKCS8 private key? - public-key

I'm developing a program with Go language for validating signatures.
It receives parameters(public key, signature, plaintext)
and the signature is signed by user's private key in PKCS#8.
I tried to use the function VerifyPKCS1v15 in the package x509
but it didn't work for me.
I guess it may due to the function is oriented for signatures made by pkcs1 private keys.
can anybody help me?
I wanna know if there is any way to validate signatures using pkcs8 public key?
this is my code
func main() {
var plainTest = "P0000000025300000100000000001000026720180705140842"
var hashVal = "15b47c1d79b0be2aae36a05bcd8644af7bfe3dd4e0c23e2b78692fc900998fca"
var signatureStr = "WWFCZsD3BhakkCaLAcTPxMvd3Pom1Glhgcc+xhR7tIDBLvkVk/LtxV+2nHw6b9u0Dcla8U4vUR7KH8zpUS7fNJD9yPDDWxH5PYiw4jQTjziiLHSUpuaGbf8N1Y2jKPXvzq1ZFaEAqCirLSmt5KyD3gQ22ysHgYA2vH44zzBApcxYXVbzLbCIGAR5aL/mvYt7uWsh4FX8dQ49v9SqIm/rRBGEbsscF4HpQApy8VqRGvq6EbwrPCfMcpwIbBHdDUR0mneaNg9GH4hozfMC08SZtAMGDk8J/NQway1FisrjpUeZfMe/hANDH1LmfrbThKDgB7WIpDryCXMTsBKjrqyArQ=="
var pubKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA17hWIujBfiqrd4o0JCEn6N1mzv94VM9LiVHoldvPRDEwCXbeoSebzZElvhkJsPl08o68g1BgRC4LpaGQDcVzwyFMs4DnXEDLapZQpTzkmXaSIYIRYER/U1OgdW5Cq2do/eTrylWdloqWuz5JL2vIr4GFycnEduYVSzFmAqucCvgGEFUxwFxtZ95BVsxfKOt7eFCJWoS0iR2/If5EMG9F6KG6DtDUWg6awN2mIbhm8fqxSF48ehCkPCN4s4YkcUlkmGYEetdBCxbaUh9/S960XjQBK3MXbLIJLgRLoEAdWJ2v6IjaEsw7dQAaMti3QOPr0x7TyHlS7rz/lyjlJjaXEQIDAQAB"
publicKeyBase64, err := base64.StdEncoding.DecodeString(pubKeyStr)
if err != nil {
fmt.Println("base64 error : " + err.Error())
}
fmt.Println("publicKeyBase64: ")
fmt.Println(string(publicKeyBase64))
pub, err := x509.ParsePKIXPublicKey(publicKeyBase64)
if err != nil {
fmt.Println("failed to parse DER encoded public key: " + err.Error())
}
switch pub := pub.(type) {
case *rsa.PublicKey:
fmt.Println("pub is of type RSA:", pub)
case *dsa.PublicKey:
fmt.Println("pub is of type DSA:", pub)
case *ecdsa.PublicKey:
fmt.Println("pub is of type ECDSA:", pub)
default:
panic("unknown type of public key")
}
publicKey, isRSAPublicKey := pub.(*rsa.PublicKey)
if !isRSAPublicKey {
fmt.Println("Public key parsed is not an RSA public key")
}
signatureBytes, _ := hex.DecodeString(signatureStr)
fmt.Println("signatureBytes : " + string(signatureBytes))
validateBytes := sha256.Sum256([]byte(plainTest))
fmt.Println("validateBytes : " + string(validateBytes[:]))
err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA256, validateBytes[:], signatureBytes)
if err != nil {
fmt.Printf("err: %v\n", err)
} else {
fmt.Printf("ok")
}
}

I got the same problem, it turns out my publicKey is wrong.
I mean not the format, but the key is not paired with the private key.
I change to another pair of key, and the code worked.

Related

Parse Ethereum private key in string in Go

I am trying really hard to convert Ethereum private keys BIP44 in string format to a type that can (*ecdsa.PrivateKey) be used by rest of the code.
import (
"crypto/x509"
"fmt"
"log"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
)
const (
privateKey2 string = "0xbacd06016aea4280e14efd7182ba18cd98bf11701943d3d47d76b04bb7baad19"
)
func main() {
_, err = x509.ParsePKCS8PrivateKey(firstKey)
if err != nil {
fmt.Println("Cannot parse private key")
}
}
Here is how a private key can be converted to Ethereum address
You need to import one additional package "crypto/ecdsa" and also remove "0x" from the private key.
privateKey, err := crypto.HexToECDSA(privateKey2)
if err != nil {
log.Fatal(err)
}
publicKey := privateKey.Public()
publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
if !ok {
log.Fatal("error casting public key to ECDSA")
}
fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)

How to marshal an ECC public or private key

Hello i'am trying to unmarshal object that contain ECC public key
but i go umarshaling error saying that can't unmarshal object properly.
i'am tring to do the followeing :
var privateKey *ecdsa.PrivateKey
var publicKey ecdsa.PublicKey
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
log.Fatalf("Failed to generate ECDSA key: %s\n", err)
}
publicKey = privateKey.PublicKey
marshalledKey, err := json.Marshal(publicKey)
if err != nil {
panic(err)
}
var unmarshalledKey ecdsa.PublicKey
err2 := json.Unmarshal(marshalledKey, &unmarshalledKey)
if err2 != nil {
panic(err2)
}
and tthe error returned from (err2) is :
panic: json: cannot unmarshal object into Go struct field PublicKey.Curve of type elliptic.Curve
and there is no way in either eliptoc or 509x function to umarshal and the curve value is alwayes null
i found the answer finally and i will post it in case somone need it.
all we need is just to creat another struct, lets name it "retrieve" and declare the value it wil read from the unmarshal.
now the ECC public key contain 3 values "curve" and will append it as json:"Curve", "Y" ans will append it as json:"Y" and we will do the same for "X"
and it will work like this :
type retrieve struct {
CurveParams *elliptic.CurveParams `json:"Curve"`
MyX *big.Int `json:"X"`
MyY *big.Int `json:"Y"`
}
//UnmarshalECCPublicKey extract ECC public key from marshaled objects
func UnmarshalECCPublicKey(object []byte) (pub ecdsa.PublicKey) {
var public ecdsa.PublicKey
rt := new(retrieve)
errmarsh := json.Unmarshal(object, &rt)
if errmarsh != nil {
fmt.Println("err at UnmarshalECCPublicKey()")
panic(errmarsh)
}
public.Curve = rt.Key.CurveParams
public.X = rt.Key.MyX
public.Y = rt.Key.MyY
mapstructure.Decode(public, &pub)
fmt.Println("Unmarshalled ECC public key : ", pub)
return
}
we will pass the the marshalled public key to UnmarshalECCPublicKey() and it will return the correct unmarshaled obj
so the coorect use will be :
var privateKey *ecdsa.PrivateKey
var publicKey ecdsa.PublicKey
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
log.Fatalf("Failed to generate ECDSA key: %s\n", err)
}
publicKey = privateKey.PublicKey
marshalledKey, err := json.Marshal(publicKey)
if err != nil {
panic(err)
}
var unmarshalledKey ecdsa.PublicKey
unmarshalledKey = UnmarshalECCPublicKey(marshalledKey)
and that should do it, u will get the ECC public unmarshalled successfully.

invalid memory address or nil pointer dereference with sql.DB

I'm learning Go at the moment and trying to make a little SQL-toolset:
type DBUtils struct {
User string
Password string
Host string
Database string
Handle *sql.DB
}
func (dbUtil DBUtils) Connect() {
var err error
dbUtil.Handle, err = sql.Open("mysql", dbUtil.User + ":" + dbUtil.Password + "#tcp(" + dbUtil.Host + ")/" + dbUtil.Database)
if err != nil {
panic(err.Error())
}
err = dbUtil.Handle.Ping()
if err != nil {
panic(err.Error())
}
fmt.Printf("%v", dbUtil)
}
func (dbUtil DBUtils) Close() {
dbUtil.Handle.Close()
}
func (dbUtil DBUtils) GetString(what string, from string, where string, wherevalue string) string {
var username string
fmt.Printf("%v", dbUtil)
stmtOut, err := dbUtil.Handle.Prepare("SELECT " + what + " FROM " + from + " WHERE " + where + " = " + wherevalue)
if err != nil {
panic(err.Error()) // proper error handling instead of panic in your app
}
err = stmtOut.QueryRow(1).Scan(&username)
return username
}
So when using this with the following code:
db := databaseutils.DBUtils{"root", "root", "127.0.0.1:3306", "gotest", nil}
db.Connect() // I get: {root root 127.0.0.1:3306 gotest 0xc42019d600}
fmt.Printf("%v", db) // I get {root root 127.0.0.1:3306 gotest <nil>}
x := db.GetString("username", "users", "id", "1") // Doesn't work: panic: runtime error: invalid memory address or nil pointer dereference
fmt.Println(x)
For me it seems like my DB handle isn't saved properly? Does anyone have an idea - I'm pretty new to go and there are many things looking different to PHP, JS, C++ etc.
Thanks in advance!
Your Connect method is not changing the state of the object you're calling the method on. You're working on a copy of the type. If you want a method to change the object itself, you'll have to define it on a pointer:
func (dbUtil *DBUtils) Connect() {
//instead of
func (dbUtil DBUtils) Connect() {
If you're familiar with C or C++, your current method works similarly to something like:
void connect_db(struct db_utils db_util)
{}
When you call a function like that, you're creating a copy of the argument, and push that on to the stack. The connect_db function will work with that, and after it returns, the copy is deallocated.
compare it to this C code:
struct foo {
int bar;
};
static
void change_copy(struct foo bar)
{
bar.bar *= 2;
}
static
void change_ptr(struct foo *bar)
{
bar->bar *= 2;
}
int main ( void )
{
struct foo bar = {10};
printf("%d\n", bar.bar);//prints 10
change_copy(bar);//pass by value
printf("%d\n", bar.bar);//still prints 10
change_ptr(&bar);
printf("%d\n", bar.bar);//prints 20
return 0;
}
The same thing happens in go. The object on which you define the method can only change state of the instance if it has access to the instance. If not, it can't update that part of the memory.
In case you're wondering, this method doesn't need to be defined on the pointer type:
func (dbUtil DBUtils) Close() {
dbUtil.Handle.Close()
}
The reason for this being that DBUtils.Handle is a pointer type. A copy of that pointer will always point to the same resource.
I will say this, though: given that you're essentially wrapping the handle, and you're exposing the Connect and Close methods, the member itself really shouldn't be exported. I'd change it to lower-case handle
You are right about your DB handle not being saved. You are defining your methods on a value receiver. Therefore you receive a copy inside the Connect method and modify said copy. This copy is then dropped at the end of the Connect method.
You have to define your method on a pointer to your structure:
func (dbUtil *DBUtils) Connect() {
var err error
dbUtil.Handle, err = sql.Open("mysql", dbUtil.User + ":" + dbUtil.Password + "#tcp(" + dbUtil.Host + ")/" + dbUtil.Database)
if err != nil {
panic(err.Error())
}
err = dbUtil.Handle.Ping()
if err != nil {
panic(err.Error())
}
fmt.Printf("%v", dbUtil)
}
For further information see https://golang.org/doc/faq#methods_on_values_or_pointers.
Note: I noticed your usage of QueryRow. It accepts arguments for parameters in your prepare statement. You have no parameters there, so I think you should not pass any parameters. You should also check the Scan result for errors (see https://golang.org/pkg/database/sql/#Stmt).

How to tell the client they need to send an integer instead of a string, from a Go server?

Let's say I have the following Go struct on the server
type account struct {
Name string
Balance int
}
I want to call json.Decode on the incoming request to parse it into an account.
var ac account
err := json.NewDecoder(r.Body).Decode(&ac)
If the client sends the following request:
{
"name": "test#example.com",
"balance": "3"
}
Decode() will return the following error:
json: cannot unmarshal string into Go value of type int
Now it's possible to parse that back into "you sent a string for Balance, but you really should have sent an integer", but it's tricky, because you don't know the field name. It also gets a lot trickier if you have a lot of fields in the request - you don't know which one failed to parse.
What's the best way to take that incoming request, in Go, and return the error message, "Balance must be a string", for any arbitrary number of integer fields on a request?
You can use a custom type with custom unmarshaling algorythm for your "Balance" field.
Now there are two possibilities:
Handle both types:
package main
import (
"encoding/json"
"fmt"
"strconv"
)
type Int int
type account struct {
Name string
Balance Int
}
func (i *Int) UnmarshalJSON(b []byte) (err error) {
var s string
err = json.Unmarshal(b, &s)
if err == nil {
var n int
n, err = strconv.Atoi(s)
if err != nil {
return
}
*i = Int(n)
return
}
var n int
err = json.Unmarshal(b, &n)
if err == nil {
*i = Int(n)
}
return
}
func main() {
for _, in := range [...]string{
`{"Name": "foo", "Balance": 42}`,
`{"Name": "foo", "Balance": "111"}`,
} {
var a account
err := json.Unmarshal([]byte(in), &a)
if err != nil {
fmt.Printf("Error decoding JSON: %v\n", err)
} else {
fmt.Printf("Decoded OK: %v\n", a)
}
}
}
Playground link.
Handle only a numeric type, and fail anything else with a sensible error:
package main
import (
"encoding/json"
"fmt"
)
type Int int
type account struct {
Name string
Balance Int
}
type FormatError struct {
Want string
Got string
Offset int64
}
func (fe *FormatError) Error() string {
return fmt.Sprintf("Invalid data format at %d: want: %s, got: %s",
fe.Offset, fe.Want, fe.Got)
}
func (i *Int) UnmarshalJSON(b []byte) (err error) {
var n int
err = json.Unmarshal(b, &n)
if err == nil {
*i = Int(n)
return
}
if ute, ok := err.(*json.UnmarshalTypeError); ok {
err = &FormatError{
Want: "number",
Got: ute.Value,
Offset: ute.Offset,
}
}
return
}
func main() {
for _, in := range [...]string{
`{"Name": "foo", "Balance": 42}`,
`{"Name": "foo", "Balance": "111"}`,
} {
var a account
err := json.Unmarshal([]byte(in), &a)
if err != nil {
fmt.Printf("Error decoding JSON: %#v\n", err)
fmt.Printf("Error decoding JSON: %v\n", err)
} else {
fmt.Printf("Decoded OK: %v\n", a)
}
}
}
Playground link.
There is a third possibility: write custom unmarshaler for the whole account type, but it requires more involved code because you'd need to actually iterate over the input JSON data using the methods of the
encoding/json.Decoder type.
After reading your
What's the best way to take that incoming request, in Go, and return the error message, "Balance must be a string", for any arbitrary number of integer fields on a request?
more carefully, I admit having a custom parser for the whole type is the only sensible possibility unless you are OK with a 3rd-party package implementing a parser supporting validation via JSON schema (I think I'd look at this first as juju is a quite established product).
A solution for this could be to use a type assertion by using a map to unmarshal the JSON data into:
type account struct {
Name string
Balance int
}
var str = `{
"name": "test#example.com",
"balance": "3"
}`
func main() {
var testing = map[string]interface{}{}
err := json.Unmarshal([]byte(str), &testing)
if err != nil {
fmt.Println(err)
}
val, ok := testing["balance"]
if !ok {
fmt.Println("missing field balance")
return
}
nv, ok := val.(float64)
if !ok {
fmt.Println("balance should be a number")
return
}
fmt.Printf("%+v\n", nv)
}
See http://play.golang.org/p/iV7Qa1RrQZ
The type assertion here is done using float64 because it is the default number type supported by Go's JSON decoder.
It should be noted that this use of interface{} is probably not worth the trouble.
The UnmarshalTypeError (https://golang.org/pkg/encoding/json/#UnmarshalFieldError) contains an Offset field that could allow retrieving the contents of the JSON data that triggered the error.
You could for example return a message of the sort:
cannot unmarshal string into Go value of type int near `"balance": "3"`
It would seem that here provides an implementation to work around this issue in Go only.
type account struct {
Name string
Balance int `json:",string"`
}
In my estimation the more correct and sustainable approach is for you to create a client library in something like JavaScript and publish it into the NPM registry for others to use (private repository would work the same way). By providing this library you can tailor the API for the consumers in a meaningful way and prevent errors creeping into your main program.

Getting json dynamic key name as string?

For example:
{"id":
{"12345678901234":
{"Account":"asdf",
"Password":"qwerty"
"LastSeen":"1397621470",
}
}
}
A program I've been trying to make needs to get the id as a string and then later use it to check the time in LastSeen.
I've tried using simplejson and jsonq,but still cant figure out how to do that.
You can use RawMessage and make it much simpiler (play with it) :
package main
import (
"encoding/json"
"fmt"
)
var data []byte = []byte(`{"id": {"12345678901234": {"Account":"asdf", "Password":"qwerty", "LastSeen":"1397621470"}}}`)
type Message struct {
Id string
Info struct {
Account string
Password string
LastSeen string
}
}
func main() {
var (
tmpmsg struct {
Data map[string]json.RawMessage `json:"id"`
}
msg Message
)
if err := json.Unmarshal(data, &tmpmsg); err != nil {
panic(err) //you probably wanna use or something instead
}
for id, raw := range tmpmsg.Data {
msg.Id = id
if err := json.Unmarshal(raw, &msg.Info); err != nil {
panic(err)
}
}
fmt.Printf("%+v\n", msg)
}
Looking at the Golang blog post on JSON here it can be done using the encoding/json package. I created a small program to do this as follows:
package main
import (
"encoding/json"
"fmt"
)
var data []byte = []byte(`{"id": {"12345678901234": {"Account":"asdf", "Password":"qwerty", "LastSeen":"1397621470"}}}`)
type Message struct {
id string
LastSeen int64
}
var m Message
func main() {
var i interface {}
err := json.Unmarshal(data, &i)
if err != nil {
println("Error decoding data")
fmt.Printf("%s", err.Error())
return
}
m := i.(map[string]interface{})
for k, v := range m {
println(k)
im := v.(map[string]interface{})
for ik, iv := range im {
println("\t", ik)
jm := iv.(map[string]interface{})
for jk, jv := range jm {
println("\t\t", jk, ": ", jv.(string))
}
}
}
}
I apologise if this is poor in terms of Go best practices and such, I am new to the language. And I know that some elements of this aren't entirely necessary like the Message type definition but this works, at least on your data.