最後因為工作需求要使用加解密,因為通常在接第三方api只會使用單一public或private key來驗證其資料是否正常,而此程式可以幫助你快速驗證public, private key是否有問題,進一步解決問題

package main

import (
    "crypto"
    "crypto/rand"
    "crypto/rsa"
    "crypto/sha256"
    "crypto/x509"
    "encoding/base64"
    "encoding/pem"
    "errors"
    "fmt"
)

func main() {
    signer, err := loadPrivateKey("private.pem")
    if err != nil {
        fmt.Errorf("signer is damaged: %v", err)
    }

    //    toSign := `{"user":"3nYTOSjdlF6UTz9Ir","country":"XX","currency":"BTC","operator_id":1,"token":"cd6bd8560f3bb8f84325152101adeb45","platform":"GPL_DESKTOP","game_id":39,"lang":"en","lobby_url":"https://examplecasino.io","ip":"::ffff:10.0.0.39"}`

    toSign := `{"operator_id":580}`

    signed, err := signer.Sign([]byte(toSign))
    if err != nil {
        fmt.Errorf("could not sign request: %v", err)
    }
    sig := base64.StdEncoding.EncodeToString(signed)
    fmt.Printf("Signature: %v\n", sig)

    parser, perr := loadPublicKey("public.pem")
    if perr != nil {
        fmt.Errorf("could not sign request: %v", err)
    }

    err = parser.Unsign([]byte(toSign), signed)
    if err != nil {
        fmt.Errorf("could not sign request: %v", err)
    }

    fmt.Printf("Unsign error: %v\n", err)
}

// loadPrivateKey loads an parses a PEM encoded private key file.
func loadPublicKey(path string) (Unsigner, error) {
    //test
//    return parsePublicKey([]byte(`-----BEGIN PUBLIC KEY-----
//MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
//6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
//Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
//oYi+1hqp1fIekaxsyQIDAQAB
//-----END PUBLIC KEY-----`))
    //our
    return parsePublicKey([]byte(`-----BEGIN PUBLIC KEY-----
AAAAB3NzaC1yc2EAAAADAQABAAABAQDoLZxKS7hmqFqACfFmoOP+FllJe6lhrrc/+gRmEQcTr3y7oeicBPNaFO9R6IPb04iMlOrBckEbei1ehawDazKRYl9mNCUi+Pbw0lEmPyG+czj1OkzdkmoH2hY/y6MCqe/TTR0RGSeXWQqQYk6nvqbOG2GgjFpczoheJTNaWanMw/iMZA2cKnYwWuuK+iqW8yJDhe22ZdpoWXWHuVHYTPOI2bL81bJj4O7CVd4hkNkXbbW51LFhl8zIZCj+KBAX97vqCI6TsbahQvzAbisaHQw3bAAHQzlZ2ypMVvaiG8NIlD78WHMhfmdtk9xGJGjfn53YwwkBD6W426ebQPO/dx7L
-----END PUBLIC KEY-----`))
}

// parsePublicKey parses a PEM encoded private key.
func parsePublicKey(pemBytes []byte) (Unsigner, error) {
    block, _ := pem.Decode(pemBytes)
    if block == nil {
        return nil, errors.New("ssh: no key found")
    }

    var rawkey interface{}
    switch block.Type {
    case "PUBLIC KEY":
        rsa, err := x509.ParsePKIXPublicKey(block.Bytes)
        if err != nil {
            return nil, err
        }
        rawkey = rsa
    default:
        return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
    }

    return newUnsignerFromKey(rawkey)
}

// loadPrivateKey loads an parses a PEM encoded private key file.
func loadPrivateKey(path string) (Signer, error) {
    //test
    //    return parsePrivateKey([]byte(`-----BEGIN RSA PRIVATE KEY-----
    //MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
    //NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
    //UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB
    //AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA
    //QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK
    //kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg
    //f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u
    //412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc
    //mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7
    //kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA
    //gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
    //G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
    //7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
    //-----END RSA PRIVATE KEY-----`))
    //our
    return parsePrivateKey([]byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA6C2cSku4ZqhagAnxZqDj/hZZSXupYa63P/oEZhEHE698u6Ho
nATzWhTvUeiD29OIjJTqwXJBG3otXoWsA2sykWJfZjQlIvj28NJRJj8hvnM49TpM
3ZJqB9oWP8ujAqnv000dERknl1kKkGJOp76mzhthoIxaXM6IXiUzWlmpzMP4jGQN
nCp2MFrrivoqlvMiQ4XttmXaaFl1h7lR2EzziNmy/NWyY+DuwlXeIZDZF221udSx
YZfMyGQo/igQF/e76giOk7G2oUL8wG4rGh0MN2wAB0M5WdsqTFb2ohvDSJQ+/Fhz
IX5nbZPcRiRo35+d2MMJAQ+luNunm0Dzv3ceywIDAQABAoIBABttd+8W7tvBu58w
jYHwM77KaRXTM/lEKIW4RVjBXjKnIncP82iq9QyJOJRWgW0wmgrxdKIRmzthvYZT
CDUHLtwZ4Ocz9cch3hoo3klEX/odpnbhwj7SkxAGZWZ36fPgm2I809g3PoQUkrjn
xB7w2Me0WF4c9nfMNjPY9S4RNYvoyQkc+rdT4/YuP8qQYfhtyaYqELcnkgeJbE7T
Fl8tuUmrXpKTUFbSK5QmS7w/fCOIbYlExw3gtP2zbzioedt4bta1OY1OSydfa1la
9ioSzZUQIabMIXkOCO6K99YHzq2KNz+bEIM95RBr60sJO+Tj0ejP74Me3uHjeFWz
y6HdpfECgYEA/Uq9MgPRMac4cfDtGOQQagQwtGEbei0HAi8DZ76shAaHIfhsMJmc
f8cMbzsOIOb7gHuL9VrX55IGEBAHl6UDtbObAtSYYEexdqXkPBCRVf4IDzR2/jKH
d7Lc3OxOyPCTy9CCTmMPuExBJC3kQCoZJHhePwXGWWtIOj2JHFbxy80CgYEA6qkV
PTJrA8oR8VdiKhMu1gI8VDV4oTQht0G3ZVzhbb5Zb7ApqJsIG3H/1MsGcXWrHOqd
o2c+xoNl78rjWMXwtRiZlOvgP+AyIvHsSgB0HSGXkRk8g/4kerK+NGUQed6Naz2/
ha81Vjy8V7Uqkahf036fG30Gs8aWVGUv1Av1bPcCgYEA8B/UsP+xaLMw7cQL4lcD
wJ3sVnThCbh6NnW/crDu99MAdRH/7ysRlIltnl2MDWEs+ScnDhlrKZvjp4Kqz/ae
R7nXsJ0/P7d35BVtBAxo2+8SUOfaDy50AuRMQhy8q/52/vfTMOD03DFeaCAhjTrb
zxlVr8WXvtnYBW6k93rti9kCgYATxooOrTgNirL2ZsnUB+fTiz6wTg1LcIxC2Fvv
Q+OPjxIUcoEgP2hwf6vyr+VsHGF+P1tnkOTeb+ZgTfXY3l2JtXgD79jnKSqwfTjP
h7hBWDpgtQK/kORcHsIewkGgM5wxZHPGfVx+VwH8Vj0vJ0RkG3CnLWMqNVsn45sj
QJq/QwKBgQDTopBcMxR30B9Ya+GZd8dpq1a7g5aV3exH6T+AXF9EAdmjRxgXJziG
wdQdD2L1kHuMQjBZgCdXIOAixiDgKil7/HVkdKhItMFndd6Pm+2lIbiYW1OXB8Lz
q1QD1TpSmP2W7VSexN0vbeDDqmXmI2HkISMyPAs7QBkjaQME7EOAwg==
-----END RSA PRIVATE KEY-----`))

}

// parsePublicKey parses a PEM encoded private key.
func parsePrivateKey(pemBytes []byte) (Signer, error) {
    block, _ := pem.Decode(pemBytes)
    if block == nil {
        return nil, errors.New("ssh: no key found")
    }

    var rawkey interface{}
    switch block.Type {
    case "RSA PRIVATE KEY":
        rsa, err := x509.ParsePKCS1PrivateKey(block.Bytes)
        if err != nil {
            return nil, err
        }
        rawkey = rsa
    default:
        return nil, fmt.Errorf("ssh: unsupported key type %q", block.Type)
    }
    return newSignerFromKey(rawkey)
}

// A Signer is can create signatures that verify against a public key.
type Signer interface {
    // Sign returns raw signature for the given data. This method
    // will apply the hash specified for the keytype to the data.
    Sign(data []byte) ([]byte, error)
}

// A Signer is can create signatures that verify against a public key.
type Unsigner interface {
    // Sign returns raw signature for the given data. This method
    // will apply the hash specified for the keytype to the data.
    Unsign(data []byte, sig []byte) error
}

func newSignerFromKey(k interface{}) (Signer, error) {
    var sshKey Signer
    switch t := k.(type) {
    case *rsa.PrivateKey:
        sshKey = &rsaPrivateKey{t}
    default:
        return nil, fmt.Errorf("ssh: unsupported key type %T", k)
    }
    return sshKey, nil
}

func newUnsignerFromKey(k interface{}) (Unsigner, error) {
    var sshKey Unsigner
    switch t := k.(type) {
    case *rsa.PublicKey:
        sshKey = &rsaPublicKey{t}
    default:
        return nil, fmt.Errorf("ssh: unsupported key type %T", k)
    }
    return sshKey, nil
}

type rsaPublicKey struct {
    *rsa.PublicKey
}

type rsaPrivateKey struct {
    *rsa.PrivateKey
}

// Sign signs data with rsa-sha256
func (r *rsaPrivateKey) Sign(data []byte) ([]byte, error) {
    h := sha256.New()
    h.Write(data)
    d := h.Sum(nil)
    return rsa.SignPKCS1v15(rand.Reader, r.PrivateKey, crypto.SHA256, d)
}

// Unsign verifies the message using a rsa-sha256 signature
func (r *rsaPublicKey) Unsign(message []byte, sig []byte) error {
    h := sha256.New()
    h.Write(message)
    d := h.Sum(nil)
    return rsa.VerifyPKCS1v15(r.PublicKey, crypto.SHA256, d, sig)
}
 

ps:正常情況下,public, private是不會出問題的,若程式跑到出錯則代表,public, private有問題無法用來驗證

創作者介紹
創作者 狼翔月影 的頭像
狼翔月影

狼翔天地

狼翔月影 發表在 痞客邦 留言(0) 人氣()