Closed kevin-liangit closed 5 years ago
Hello.
The hash produced by -subject_hash_old
is not a hash over the entire certificate (which is what your code is calculating). It is instead an md5 hash of the asn.1 encoding of the certificate subject extension (the first four bytes of the digest are then stuffed into an uint32 in little endian ordering). You don't need this library to accomplish this. Here is some code that does this (error checking is omitted):
$ openssl x509 -noout -subject_hash_old -in cacert.pem
543b6ca4
$ go run subhash.go cacert.pem
543b6ca4
$ cat subhash.go
package main
import (
"crypto/md5"
"crypto/x509"
"encoding/asn1"
"encoding/binary"
"encoding/pem"
"fmt"
"io/ioutil"
"os"
)
func main() {
pemBytes, _ := ioutil.ReadFile(os.Args[1])
block, _ := pem.Decode(pemBytes)
cert, _ := x509.ParseCertificate(block.Bytes)
sub, _ := asn1.Marshal(cert.Subject.ToRDNSequence())
digest := md5.Sum(sub)
hash := binary.LittleEndian.Uint32(digest[:4])
fmt.Printf("%x\n", hash)
}
thanks azdraon. No luck but I do want to point out that my cert is in the format as so:
-----BEGIN CERTIFICATE----- BLOCK -----END CERTIFICATE-----
The code above expects that format. If you fill in the error handling, is the code failing at one of the steps above?
kevins-mbp:CSVReader kevinliang$ go run hash.go 68880a30
this is the response i get, so no error. Oddly when i outpued the error it did complain at
block,err4 := pem.Decode(pemBytes)
if err!=nil{
fmt.Println(err, "ERROR")
}
your error handling above is not correct. try the following:
package main
import (
"crypto/md5"
"crypto/x509"
"encoding/asn1"
"encoding/binary"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"os"
)
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
func run() error {
if len(os.Args) < 2 {
return errors.New("missing path to certificate")
}
pemBytes, err := ioutil.ReadFile(os.Args[1])
if err != nil {
return fmt.Errorf("unable to open certificate: %v", err)
}
block, _ := pem.Decode(pemBytes)
if block == nil {
return errors.New("failed to decode PEM")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return fmt.Errorf("failed to parse certificate from PEM: %v", err)
}
sub, err := asn1.Marshal(cert.Subject.ToRDNSequence())
if err != nil {
return fmt.Errorf("failed to asn.1 encode certificate subject: %v", err)
}
digest := md5.Sum(sub)
hash := binary.LittleEndian.Uint32(digest[:4])
fmt.Printf("%x\n", hash)
return nil
}
I am still getting 68880a30 , there was zero error output
wmachs-iphone:platform-tools kevinliang$ openssl x509 -noout -subject_hash -in ../charles-ssl-proxying-certificate.pem e3f5f47d wmachs-iphone:platform-tools kevinliang$ openssl x509 -noout -subject_hash_old -in ../charles-ssl-proxying-certificate.pem e64b3453
¯_(ツ)_/¯
Not sure what is happening exactly. If I had your certificate I could probably figure it out. In any case, if you are interested in the exact behavior of openssl, you could always add some methods to the Certificate
struct (in this library) that wrap the X509_subject_name_hash
and X509_subject_name_hash_old
methods out of openssl (with appropriate stubs, since X509_subject_name_hash_old
didn't always exist, and is also not available if MD5 support is compiled out of openssl).
You could use my repo for doing this: rsa
There are both subject_hash_old
and issuer_hash_old
Hi all,
First time posting here. I am looking to get the subject_hash (md5) for my pem file, as you would with command line openssl
wmachs-iphone:platform-tools user$ openssl x509 -noout -subject_hash_old -in ../charles-ssl-proxying-certificate.pem e64b345
I tried using the spacemonkey library but was not successful. What am I doing wrong?
RESPONSE
[150 21 143 243 26 230 95 234 154 135 143 103 234 127 200 228]
d41d8cd98f00b204e9800998ecf8427e