2015-10-23 6 views
0

Я пытаюсь загрузить АСС закрытый ключ в моей программе, Вот как я подошел к нему:нагрузки (OpenSSL генерироваться) DSA закрытый ключ из файла PEM

  1. создать пару ключей DSA с помощью OpenSSL :

    openssl dsaparam -genkey 2048 -out dsakey.pem 
    
  2. Я использую следующие функции для разбора файла PEM

    func getDSAPrivateKeyFromPemFile(pemfilepath string) (recoveredprivateKey *dsa.PrivateKey, err error) { 
    pemfile, err := os.Open(pemfilepath) 
    if err != nil { 
        return nil, err 
    } 
    recoveredbytes, err := ioutil.ReadAll(pemfile) 
    if err != nil { 
        return nil, err 
    } 
    
    recoveredpemdsaparameteres, rest := pem.Decode(recoveredbytes) 
    if recoveredpemdsaparameteres == nil { 
        return nil, errors.New("No pem recovered") 
    } 
    
    _, err = asn1.Unmarshal(append(recoveredpemdsaparameteres.Bytes, recoveredpemdsaprivatekey.Bytes...), recoveredprivateKey) 
    if err != nil { 
        return nil, err 
    } 
    fmt.Printf("PEM:%v\n", recoveredpemdsaparameteres) 
    
    recoveredpemdsaprivatekey, _ := pem.Decode(rest) 
    fmt.Printf("PEM:%v\n", recoveredpemdsaprivatekey) 
    pemfile.Close() 
    } 
    

Когда я вызываю эту функцию, если не удается:

panic: reflect: call of reflect.Value.Type on zero Value 

goroutine 1 [running]: 
reflect.Value.Type(0x0, 0x0, 0x0, 0x0, 0x0) 
    /usr/local/go/src/reflect/value.go:1664 +0x7b 
encoding/asn1.parseField(0x0, 0x0, 0x0, 0xc8200b0600, 0x58b, 0x600, 0x0, 0x0, 0x0, 0x0, ...) 
    /usr/local/go/src/encoding/asn1/asn1.go:558 +0xbd 
encoding/asn1.UnmarshalWithParams(0xc8200b0600, 0x58b, 0x600, 0x1383e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ...) 
    /usr/local/go/src/encoding/asn1/asn1.go:957 +0x16e 
encoding/asn1.Unmarshal(0xc8200b0600, 0x58b, 0x600, 0x1383e0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) 
    /usr/local/go/src/encoding/asn1/asn1.go:950 +0x8f 
main.getDSAPrivateKeyFromPemFile(0x1e7fa0, 0x26, 0x0, 0x0, 0x0) 

Однако, я могу прекрасно видеть мой ключ DSA на выходе:

PEM:&{DSA PARAMETERS map[] [48 130 2 45 2 130...]} 
PEM:&{DSA PRIVATE KEY map[] [48 130 3 86 2 1 0 ...]} 

Проблема в том, как распаковать PEM байт в dsa.PrivateKey , Любые идеи?

P.S: Я не смог найти какой-либо пример загрузки файла приватного ключа DSA через Интернет.

+2

только сторона примечания: вы должны либо выбрать более короткие имена переменных, либо использовать их в camelCase, так как «recoveredpemdsaparameteres» не только трудно читать, но и после тщательного осмотра неверно. – mrd0ll4r

+0

Паника - это потому, что 'recoveredprivateKey' равен нулю. Выделите структуру, прежде чем пытаться ее развязать. – JimB

+0

@JimB да, но это не решило проблему, поскольку у меня была другая паника из-за несоответствия структуры. См. Мой ответ ... Я был бы более чем счастлив, если он будет работать из коробки! –

ответ

1

Проведя пару часов, мне удалось исправить мою проблему я отправляю мой вывод так что это может спасти чью-то время:

Сначала я рассмотрел мою кодировку PEM файл, используя этот большой онлайн инструмент: http://lapo.it/asn1js/. Только тогда я понял, что Go ожидает, что файл pem будет иметь другую структуру ... Не красиво! Aftwerwards, было непросто связать каждое значение внутри файла с соответствующей структурой dsa.PrivateKey. Итак, я сделал новый структура и назвал его MyPrivateKey с тем же порядком, что и файл PEM:

type MyPrivateKey struct { 
    E1, P, Q, G, Y, X *big.Int 
} 

Затем, вместо того, чтобы пытаться распаковать непосредственно dsa.PrivateKey, я unmarshaled в ASN1 закодированное значение для моей самости сделанная структура. И волшебным образом это сработало. Вот измененная функция:

func getDSAPrivateKeyFromPemFile(pemFilePath string) (privateKey *dsa.PrivateKey, err error) { 
    pemfile, err := os.Open(pemFilePath) 

    if err != nil { 
     return nil, err 
    } 
    recoveredBytes, err := ioutil.ReadAll(pemfile) 
    if err != nil { 
     return nil, err 
    } 
    pemfile.Close() 

    pemDSAParameters, rest := pem.Decode(recoveredBytes) 
    if pemDSAParameters == nil { 
     return nil, errors.New("No pem recovered") 
    } 
    pemDSAPrivateKey, _ := pem.Decode(rest) 
    keyParameters := dsa.Parameters{G: big.NewInt(0), P: big.NewInt(0), Q: big.NewInt(0)} 
    _, err = asn1.Unmarshal(pemDSAParameters.Bytes, &keyParameters) 
    if err != nil { 
     return nil, err 
    } 
    //fmt.Printf("\n\n\n\n\n\nP:%x\n\nG:%x\n\nQ:%x\n\n\n\n\n\n", keyParameters.P, keyParameters.G, keyParameters.Q) 
    myPrivateKey := MyPrivateKey{} 
    _, err = asn1.Unmarshal(pemDSAPrivateKey.Bytes, &myPrivateKey) 
    if err != nil { 
     return nil, err 
    } 
    //fmt.Printf("\nprivate\nE1:%x\n\nP:%x\n\nQ:%x\n\nG:%x\n\nY:%x\nX:%x\n\n\n\n", myPrivateKey.E1, myPrivateKey.P, myPrivateKey.Q, myPrivateKey.G, myPrivateKey.Y, myPrivateKey.X) 
    privateKey = &dsa.PrivateKey{} 
    privateKey.Parameters = keyParameters 
    privateKey.X = myPrivateKey.X 

    return privateKey, nil 
} 

Возможно, для этого все было намного проще, и я просто упустил из виду! Если вы знаете лучший способ, пожалуйста, будь моим гостем! В противном случае, я думаю, go должен справиться с такими проблемами в стандартных библиотеках.

+0

есть реализация в golang/crypto: https://github.com/golang/crypto/blob/master/ssh/keys.go#L869 – xjdrew

Смежные вопросы