[erlang-questions] ECC public key example
Ben Hood
0x6e6562@REDACTED
Sat Jul 27 16:39:53 CEST 2013
Hi Gustav,
Thank you very much for deciphering the API for me :-)
Using your example as inspiration, I was able to sign and verify some
data with the key pair generated using openssl:
$ openssl ecparam -out ecdsa.pem -name sect571r1 -genkey
$ openssl ec -in ecdsa.pem -pubout -out ecdsa.pub
I take your point about how you pulled the ECParams out of the private
key, although this is actually necessary to construct the public key.
However, I was able to extract this out of the SPKI stanza:
#'SubjectPublicKeyInfo'{algorithm = #'AlgorithmIdentifier'{algorithm =
{1,2,840,10045,2,1},
parameters = <<6,5,43,129,4,0,39>>},
subjectPublicKey = {0,
<<4,4,179,52,127,201,246,179,111,174,210,158,176,114,47,
61,131,42,95,74,96,132,1,196,...>>}},
EcpkParametersPem = {'EcpkParameters', <<6,5,43,129,4,0,39>>, not_encrypted},
ECParams = public_key:pem_entry_decode(EcpkParametersPem).
As for the issue with the OTPEcpkParameters pattern mismatch, judging
from the ASN.1 definitions for the public_key module in R16B01, I
think that the entity has somehow been prefixed with OTP by mistake.
Previously to parse the private key file I had taken the same approach
- see my original post. I too would question whether the ASN.1 schema
is correct in this regard.
Anyway, although you have to jump through a number of hoops, ECC
signature verification in Erlang is now working for me.
Thanks very much for your help.
Cheers,
Ben
On Sat, Jul 27, 2013 at 3:10 PM, Gustav Simonsson
<gustav.simonsson@REDACTED> wrote:
> 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
>
>
More information about the erlang-questions
mailing list