[erlang-questions] ECC public key example

Gustav Simonsson gustav.simonsson@REDACTED
Sat Jul 27 16:10:32 CEST 2013


Hi Ben,

I've replicated your console commands (see end of mail) and continued with
steps which end with a successful verification of the signature with the EC
Public Key.
Some duplicated commands is removed from the log but it should still
contain all the necessary steps.

Some things I noticed:

* There is one SubjectPublicKeyInfo which contains another
SubjectPublicKeyInfo.
   This doesn't seem correct and I'm not really sure where the error
causing this is.

* The EC Public Key type in public_key is defined as:

ec_public_key()  = {#'ECPoint'{}, #'EcpkParameters'{} | {namedCurve, oid()}}

But the EC Public Key Parameters are actually returned as a
'OTPEcpkParameters' PEM entry (record)
whose record definition is missing. I suspect this could be a bug in
public_key.

* I didn't find a way to get a #'ECPoint' record back from decoding, so I
manually created it by
   matching out the ECPoint octets from the SPKI record.

* As the EC parameters was in the private key file, they had to be manually
combined with the ECPoint
   to form the EC Public Key. Maybe it's possible to tell openssl to
include the EC parameters in the public
   key file with some option?

Test keys where generated with:

openssl ecparam -out ec_key_priv.pem -name prime192v1 -genkey
openssl ec -pubout -in ec_key_priv.pem -out ec_key_pub.pem

Cheers,
Gustav Simonsson

Erlang console log:
==================

Erlang R16B01 (erts-5.10.2) [source] [64-bit] [smp:4:4] [async-threads:10]
[hipe] [kernel-poll:false]

Eshell V5.10.2  (abort with ^G)
1> rr(public_key).
['AAControls','ACClearAttrs','AccessDescription',
 'Algorithm','AlgorithmIdentifier',
 'AlgorithmIdentifierPKCS-10','AlgorithmIdentifierPKCS-8',
 'AlgorithmIdentifierPKCS5v2-0','AlgorithmIdentifierPKSC-7',
 'AlgorithmNull','AnotherName','AttCertValidityPeriod',
 'Attribute','AttributeCertificate',
 'AttributeCertificateInfo','AttributePKCS-10',
 'AttributePKCS-7','AttributeTypeAndValue',
 'Attributes_SETOF',
 'Attributes_SETOF_valuesWithContext_SETOF',
 'AuthorityKeyIdentifier','BasicConstraints',
 'BuiltInDomainDefinedAttribute','BuiltInStandardAttributes',
 'Certificate','CertificateList','CertificationRequest',
 'CertificationRequestInfo',
 'CertificationRequestInfo_attributes_SETOF'|...]
2> {ok, Bin} = file:read_file("ec_key_priv.pem").
{ok,<<"-----BEGIN EC PARAMETERS-----\nBggqhkjOPQMBAQ==\n-----END EC
PARAMETERS-----\n-----BEGIN EC PRIVATE KEY-----\nMF"...>>}
3> {ok, Bin2} = file:read_file("ec_key_pub.pem").
{ok,<<"-----BEGIN PUBLIC
KEY-----\nMEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEUzzXw5xYnyZKIzSIo1xKN3enUe3M\nWSURKrWKOUB+Of+e"...>>}
4> [OTPEcpkParamsPem, ECPrivateKeyPem] = public_key:pem_decode(Bin).
[{'OTPEcpkParameters',<<6,8,42,134,72,206,61,3,1,1>>,
                      not_encrypted},
 {'ECPrivateKey',<<48,95,2,1,1,4,24,233,53,27,191,96,145,
                   18,240,229,16,151,232,48,95,167,203,176,
                   145,...>>,
                 not_encrypted}]
5> ECPrivateKey = public_key:pem_entry_decode(ECPrivateKeyPem).
#'ECPrivateKey'{version = 1,
                privateKey = [233,53,27,191,96,145,18,240,229,16,151,232,48,
                              95,167,203,176,145,117,205,108,210,242,204],
                parameters = {namedCurve,{1,2,840,10045,3,1,1}},
                publicKey = {0,

<<4,83,60,215,195,156,88,159,38,74,35,52,136,163,92,
                               74,55,119,167,81,237,204,...>>}}
6> {_, ParamsBin, ParamsEnc} = OTPEcpkParamsPem.
{'OTPEcpkParameters',<<6,8,42,134,72,206,61,3,1,1>>,
                     not_encrypted}
7> EcpkParametersPem = {'EcpkParameters', ParamsBin, ParamsEnc}.
{'EcpkParameters',<<6,8,42,134,72,206,61,3,1,1>>,
                  not_encrypted}
8> ECParams = public_key:pem_entry_decode(EcpkParametersPem).
{namedCurve,{1,2,840,10045,3,1,1}}
9> Msg = <<"The superhamster strikes again at 7PM">>.
<<"The superhamster strikes again at 7PM">>
10> Sig = public_key:sign(Msg, sha256, ECPrivateKey).
<<48,53,2,25,0,233,72,76,239,158,251,181,114,254,166,85,
  195,11,179,248,53,150,58,138,93,86,76,171,41,...>>
11> [SPKI] = public_key:pem_decode(Bin2).
[#'SubjectPublicKeyInfo'{algorithm = <<48,73,48,19,6,7,42,
                                       134,72,206,61,2,1,
                                       6,8,42,134,72,206,
                                       61,3,1,1,3,50,0,...>>,
                         subjectPublicKey = not_encrypted}]
12> #'SubjectPublicKeyInfo'{algorithm = Der} = SPKI.
#'SubjectPublicKeyInfo'{algorithm = <<48,73,48,19,6,7,42,
                                      134,72,206,61,2,1,6,
                                      8,42,134,72,206,61,
                                      3,1,1,3,50,0,4,...>>,
                        subjectPublicKey = not_encrypted}
14> RealSPKI = public_key:der_decode('SubjectPublicKeyInfo', Der).
#'SubjectPublicKeyInfo'{
    algorithm =
        #'AlgorithmIdentifier'{
            algorithm = {1,2,840,10045,2,1},
            parameters = <<6,8,42,134,72,206,61,3,1,1>>},
    subjectPublicKey =
        {0,
         <<4,83,60,215,195,156,88,159,38,74,35,52,136,163,92,74,
           55,119,167,81,237,204,89,37,...>>}}
15> #'SubjectPublicKeyInfo'{subjectPublicKey = {_, Octets}} = RealSPKI.
#'SubjectPublicKeyInfo'{
    algorithm =
        #'AlgorithmIdentifier'{
            algorithm = {1,2,840,10045,2,1},
            parameters = <<6,8,42,134,72,206,61,3,1,1>>},
    subjectPublicKey =
        {0,
         <<4,83,60,215,195,156,88,159,38,74,35,52,136,163,92,74,
           55,119,167,81,237,204,89,37,...>>}}
16> ECPoint = #'ECPoint'{point = Octets}.
#'ECPoint'{point = <<4,83,60,215,195,156,88,159,38,74,35,
                     52,136,163,92,74,55,119,167,81,237,
                     204,89,37,17,42,181,...>>}
18> ECPublicKey = {ECPoint, ECParams}.
{#'ECPoint'{point = <<4,83,60,215,195,156,88,159,38,74,
                      35,52,136,163,92,74,55,119,167,81,
                      237,204,89,37,17,42,...>>},
 {namedCurve,{1,2,840,10045,3,1,1}}}
19> public_key:verify(Msg, sha256, Sig, ECPublicKey).
true

=============================


On Fri, Jul 26, 2013 at 7:38 PM, Ben Hood <0x6e6562@REDACTED> wrote:

> Hi,
>
> I'd like to verify signatures signed with ec keys generated by openssl
> in Erlang.
>
> Using R16B01 I've been able to convince the public_key module to sign
> some data with an openssl generated private key thusly:
>
> {ok, Pem} = file:read_file("ec_private_key.pem"),
> [ECParameters,ECPrivateKey] = public_key:pem_decode(Pem),
> PrivateKey = public_key:pem_entry_decode(ECPrivateKey),
> Curve = public_key:pem_entry_decode({'EcpkParameters', Params, Enc}),
> Sig = public_key:sign(Message, sha512, PrivateKey).
>
> But when it comes to processing the public key, it is not entirely
> clear how to decode it. This is where I got to:
>
> {ok, Pem} = file:read_file("ec_public_key.pem"),
> [{_,Der,_}] = public_key:pem_decode(Pem),
> {_, _, {0, KeyDer}} = public_key:der_decode('SubjectPublicKeyInfo', Der),
> [179,52,127,201] = public_key:der_decode('ECPoint', KeyDer)
> %% This is where the story ends
>
> I've looked through the ASN.1 types available and there doesn't seem
> to be anything that resembles an ECPublicKey.
>
> Could anybody point me to working example?
>
> Cheers,
>
> Ben
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20130727/1309bcc2/attachment.htm>


More information about the erlang-questions mailing list