<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Konstantin Shemyak - Tech Notes (Posts about elliptic curves)</title><link>https://technotes.shemyak.com/</link><description></description><atom:link href="https://technotes.shemyak.com/categories/elliptic-curves.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2021 &lt;a href="mailto:konstantin@shemyak.com"&gt;Konstantin Shemyak&lt;/a&gt; </copyright><lastBuildDate>Fri, 02 Apr 2021 15:51:34 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Support for elliptic curves by jarsigner</title><link>https://technotes.shemyak.com/posts/support-for-elliptic-curves-by-jarsigner/</link><dc:creator>Konstantin Shemyak</dc:creator><description>&lt;div&gt;&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; Support for cryptography features by jarsigner depends on available Java crypto providers.&lt;/p&gt;
&lt;p&gt;Suppose you are defining a PKI profile. You naturally want to use the
stronger algorithms with better performance, which (as of year 2014)
means elliptic curves. Besides bit strength and performance,
you want to be sure that the curve is supported by your software.
If the latter includes &lt;strong&gt;jarsigner&lt;/strong&gt;, you'll be surprised to find that 
&lt;a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jarsigner.html"&gt;Oracle documentation&lt;/a&gt;
seems to not mention at all, 
&lt;em&gt;which elliptic curves does jarsigner support&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Signing a JAR means adding digests of the JAR entries to the &lt;em&gt;manifest file&lt;/em&gt;
(&lt;code&gt;META-INF/*.MF&lt;/code&gt;),
adding digest of the latter to the &lt;em&gt;manifest signature file&lt;/em&gt;
(&lt;code&gt;META-INF/*.EC&lt;/code&gt;, in case &lt;code&gt;E&lt;/code&gt;lliptic &lt;code&gt;C&lt;/code&gt;urve is used),
and then creating the
&lt;a href="https://technotes.shemyak.com/posts/jar-signature-block-file-format/"&gt;JAR signature block file&lt;/a&gt;.
The last step involves two operations:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;calculating a digest over the &lt;em&gt;manifest signature file&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;signing (i.e. encrypting with the private key) that digest.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Jarsigner has an option &lt;code&gt;-sigalg&lt;/code&gt;,
which is supposed to specify the two algorithms used in these two steps.
(There is also &lt;code&gt;-digestalg&lt;/code&gt;' option, but it is not used for the signature
block file; it defines the algorithm used in the two initial steps.)
Well, this option is irrelevant for our question: the curve is in fact
defined by the provided private key. So jarsigner will either do the job
or choke on the key which comes from an unsupported curve.&lt;/p&gt;
&lt;p&gt;A curve may "not work" because it is unknown to jarsigner itself, or to
an underlying crypto provider. (The latter case was a reason to a
&lt;a href="https://bugs.launchpad.net/ubuntu/+source/openjdk-6/+bug/1006776"&gt;bug 1006776&lt;/a&gt;,
a setup where only three curves actually worked.) Attempt to sign the JAR 
with &lt;code&gt;jarsigner&lt;/code&gt; using a non-supported private key would result in a
not very helpful error message:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;certificate&lt;/span&gt; &lt;span class="k"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IOException&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;subject&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Could&lt;/span&gt; &lt;span class="k"&gt;not&lt;/span&gt; &lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="n"&gt;EC&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;key&lt;/span&gt;
&lt;/pre&gt;


&lt;p&gt;To be on the safe side, it's best to test. For curves, supported by OpenSSL,
the test can be done by creating the keypair on each curve and attempting
the signing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Create the list of curves with &lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;openssl&lt;/span&gt; &lt;span class="n"&gt;ecparam&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;list_curves&lt;/span&gt;
&lt;/pre&gt;


&lt;ul&gt;
&lt;li&gt;remove manually some extra words openssl puts there in the beginning&lt;/li&gt;
&lt;li&gt;and feed it to the stdin:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;  &lt;span class="c1"&gt;#!/bin/bash&lt;/span&gt;
  &lt;span class="c1"&gt;# Test, which OpenSSL-supported elliptic curves from the list are supported also by jarsigner.&lt;/span&gt;
  &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"supported- curves.txt"&lt;/span&gt;
  &lt;span class="nv"&gt;source_data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"data.txt"&lt;/span&gt;
  &lt;span class="nv"&gt;jar&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"data.jar"&lt;/span&gt;
  &lt;span class="nv"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"key.pem"&lt;/span&gt;
  &lt;span class="nv"&gt;cert&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cert.pem"&lt;/span&gt;
  &lt;span class="nv"&gt;pfx&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"keystore.pfx"&lt;/span&gt;
  &lt;span class="nv"&gt;key_alias&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"foo"&lt;/span&gt;         &lt;span class="c1"&gt;# Identificator of the key in the keystore&lt;/span&gt;
  &lt;span class="nv"&gt;storepass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"123456"&lt;/span&gt;      &lt;span class="c1"&gt;# jarsigner requires some&lt;/span&gt;

  touch &lt;span class="nv"&gt;$source_data&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; curve&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c1"&gt;# Generate an ECDSA private key for the selected curve:&lt;/span&gt;
    openssl ecparam -name &lt;span class="nv"&gt;$curve&lt;/span&gt; -genkey -out &lt;span class="nv"&gt;$key&lt;/span&gt;
    &lt;span class="c1"&gt;# Generate the certificate for the key; give some dummy subject:&lt;/span&gt;
    openssl req -new -x509 -nodes -key &lt;span class="nv"&gt;$key&lt;/span&gt; -out &lt;span class="nv"&gt;$cert&lt;/span&gt; -subj /CN&lt;span class="o"&gt;=&lt;/span&gt;foo
    &lt;span class="c1"&gt;# Wrap key+cert in a PKCS12, so that jarsigner can use it:&lt;/span&gt;
    openssl pkcs12 -export -in &lt;span class="nv"&gt;$cert&lt;/span&gt; -inkey &lt;span class="nv"&gt;$key&lt;/span&gt; -passout pass:&lt;span class="nv"&gt;$storepass&lt;/span&gt; -out &lt;span class="nv"&gt;$pfx&lt;/span&gt; -name &lt;span class="nv"&gt;$key_alias&lt;/span&gt;
    &lt;span class="c1"&gt;# Create a fresh jar and attempt to sign it&lt;/span&gt;
    jar cf &lt;span class="nv"&gt;$jar&lt;/span&gt; &lt;span class="nv"&gt;$source_data&lt;/span&gt;
    jarsigner -keystore &lt;span class="nv"&gt;$pfx&lt;/span&gt; -storetype PKCS12 -storepass &lt;span class="nv"&gt;$storepass&lt;/span&gt; &lt;span class="nv"&gt;$jar&lt;/span&gt; &lt;span class="nv"&gt;$key_alias&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; -eq &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$curve&lt;/span&gt; &amp;gt;&amp;gt; &lt;span class="nv"&gt;$result&lt;/span&gt;
  &lt;span class="k"&gt;done&lt;/span&gt;
  rm &lt;span class="nv"&gt;$source_data&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="nv"&gt;$cert&lt;/span&gt; &lt;span class="nv"&gt;$pfx&lt;/span&gt; &lt;span class="nv"&gt;$jar&lt;/span&gt;
&lt;/pre&gt;


&lt;p&gt;And enjoy the list in &lt;code&gt;supported-curves.txt&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;support of elliptic curves by &lt;b&gt;jarsigner&lt;/b&gt; depends on jarsigner itself and on the used JRE.&lt;/li&gt;
&lt;li&gt;There is no command-line option to list all supported curves.&lt;/li&gt;
&lt;li&gt;For a particular system, support for curves known by &lt;b&gt;OpenSSL&lt;/b&gt; can be easily tested.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;</description><category>elliptic curves</category><category>jarsigner</category><category>openssl</category><guid>https://technotes.shemyak.com/posts/support-for-elliptic-curves-by-jarsigner/</guid><pubDate>Sun, 21 Dec 2014 19:45:00 GMT</pubDate></item></channel></rss>