2013-12-18 12 views
5

में आरएसए-एसएचए के साथ साइनिंग और डिकोडिंग मैं एक स्ट्रिंग पर हस्ताक्षर करने की कोशिश कर रहा हूं और बाद में इसे सार्वजनिक कुंजी के साथ सत्यापित करने की कोशिश कर रहा हूं। मेरा सत्यापित परिणाम खाली है। मैं क्या गलत कर रहा हूं?जाओ

package main 

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

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

    toSign := "date: Thu, 05 Jan 2012 21:31:40 GMT"; 

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


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

    fmt.Printf("Decrypted: %v\n", base64.StdEncoding.EncodeToString(unsigned))  
} 


// loadPrivateKey loads an parses a PEM encoded private key file. 
func loadPublicKey(path string) (Unsigner, error) { 
     data, err := ioutil.ReadFile(path) 

     if err != nil { 
       return nil, err 
     } 
     return parsePublicKey(data) 
} 

// 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) { 
     data, err := ioutil.ReadFile(path) 
     if err != nil { 
       return nil, err 
     } 
     return parsePrivateKey(data) 
} 

// 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) ([]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 encrypts data with rsa-sha256 
func (r *rsaPublicKey) Unsign(message []byte) ([]byte, error) { 
     return rsa.EncryptPKCS1v15(rand.Reader, r.PublicKey, message)   
} 

private.pem इस तरह दिखता है:

-----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----- 

और public.pem:

-----BEGIN PUBLIC KEY----- 
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3 
6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6 
Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw 
oYi+1hqp1fIekaxsyQIDAQAB 
-----END PUBLIC KEY----- 

धन्यवाद।

+0

मैं थोड़ा उलझन में हूं। क्या आप एन्कोड करना चाहते हैं और फिर डीकोड करना चाहते हैं, या साइन इन करें और फिर हस्ताक्षर सत्यापित करें? (मैं क्रिप्टो शब्दावली के साथ भी उपयोग नहीं किया जाता) – ANisus

+0

मैं साइन हस्ताक्षर करना और हस्ताक्षर करना चाहता हूं। अद्यतन विवरण। –

+0

चेतावनी दीजिये कि - लोकप्रिय धारणा के विपरीत - आरएसए एन्क्रिप्शन/डिक्रिप्शन एक हैश के साथ आरएसए हस्ताक्षर/सत्यापन से अलग है। कम से कम, यह एक अलग पैडिंग तंत्र का उपयोग करता है। –

उत्तर

6

आपके कोड में समस्या यह है कि Unsign मूल संदेश को सत्यापित करने के लिए इसका उपयोग करने के बजाय हस्ताक्षर को एन्कोड करने का प्रयास करता है।

वहाँ इंटरफ़ेस करने के लिए और Unsign में किए गए परिवर्तनों की जरूरत है: http://play.golang.org/p/bzpD7Pa9mr

कुछ संशोधनों भी ioutils से बचने के लिए किया गया है:

// 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) 
} 

यहाँ सत्यापन का एक खेल का मैदान उदाहरण है।

+0

playgroud नहीं चलाया जा सकता है। –

+0

@buzz: हम्म, मैंने बस अपने खेल के मैदान लिंक पर क्लिक किया और रन दबाया। यह ठीक काम किया। क्या आप स्थानीय स्तर पर खेल का मैदान कोड आजमा रहे हैं? – ANisus

+0

ओह क्षमा करें, यह मेरी गलती है। मैने एक गलती की। –