u-ryo's blog

various information for coding...

Category: Ssl

Illegal Keysize

| Comments

AndroidでNanoHTTPDを 動かすprogramを開発しているんですが、 WebRTCにするのに、TLSが必要じゃないですか。 そのserver certを普通に作ると、Illegal keysizeと言われて key load時に落ちるのでハマりました。 NanoHTTPDの解説にあるように、

1
$ keytool -genkey -keyalg RSA -alias selfsigned -keystore keystore.jks -storepass password -validity 360 -keysize 2048 -ext SAN=DNS:localhost,IP:127.0.0.1  -validity 9999

と作ってもダメでした。 色々調べると、AndroidにはBouncyCastle(BKS)でないとならないらしく、 証明書は面倒なのでsnakeoilを流用して、

1
2
$ sudo openssl pkcs12 -export -in /etc/ssl/certs/ssl-cert-snakeoil.pem -inkey /etc/ssl/private/ssl-cert-snakeoil.key -out ~/AndroidStudioProjects/SharedEye/ssl-cert-snakeoil.p12 -name ssl-cert-snakeoil
$ /usr/lib/jvm/java-8-oracle/bin/keytool -importkeystore -deststorepass password -destkeypass password -destkeystore snakeoil.jks -srckeystore ssl-cert-snakeoil.p12 -srcstoretype PKCS12 -srcstorepass password -storetype BKS -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath bcprov-jdk15-1.46.jar

とすると、

1
Problem importing entry for alias java.security.KeyStoreException: java.io.IOException: Error initialising store of key store: java.security.InvalidKeyException: Illegal key size.

と言われてimport出来ませんでした(→jksが作れませんでした)。 かなり悩んだのですが、結局JavaでAES256を使用できるようにするにあるように、 JCE(Java Cryptography Extension)を落としてきて local_policy.jarを上書きしたら、 jksも出来て、Android側でも何事もなくloadしてくれました。

Let's Encrypt Without Certbot-auto

| Comments

Let's Encrypt、素晴らしいんだけど、 とあるserverで、使っているのがUbuntu 11.04(Natty)、 package systemが何か壊れてて、 依存関係がおかしくて解消できなくて、 というcaseがありました。 基本的にどこを調べても、 Let's Encryptを使うには既存のpackaging systemをbaseにしたものばかりで、 Stackoverflowなんかでも「backportsを使って既存のpackaging依存関係を 修築してから」なんていう話しかなくて。 なんかこう、certobot-autoを使わないで、 っていう話って意外となくて途方に暮れていると、 こんなのがありました。

An ACME Shell script: acme.sh

要は、bashだけでLet's Encryptの証明書を使える、 というもので、 なーんだ最初から全部これでいーじゃん、 という感じです。

wget -O - https://get.acme.sh | shでも行けるというのですが、 何かserver certが違うらしく、--no-check-certificateを付けてもうまく行かず。 幸いgitはあってくれたので、cloneしてcd acme.sh ./acme.sh --installすると、 home直下に.acme.shというdirectoryを掘り、 その下にCSRやLet's Encryptからの証明書を自動で作ってくれる、 更に実行userでcron登録してくれる、 というものなので、実行だけならroot権限不要とはいえ、 証明書filesが一般user home directory以下というのもなんなので、 rootでやった方が良さげです。 というわけで、

1
2
3
4
5
6
7
8
9
10
11
# git clone https://github.com/Neilpang/acme.sh
# cd acme.sh
# ./acme.sh --install
# ./acme.sh --issue -d dev.locationsupporter.info -w /var/lib/tomcat7/webapps/ROOT/
# vi /etc/apache2/sites-enabled/default-ssl
=============================================
SSLCertificateFile /root/.acme.sh/dev.locationsupporter.info.cer
SSLCertificateKeyFile /root/.acme.sh/dev.locationsupporter.info.key
SSLCertificateChainFile /root/.acme.sh/fullchain.cer
=============================================
# crontab -l

これで、pytho2.7もpackage updateも不要だし、 更にお手軽にLet's Encryptを使えるというものでしょう。

Let's Encrypt

| Comments

Let's Encrypt、 漸く使えるようになりました。 具体的にどうやって使ったらいいんだろう、 と思ってたんですが、結構簡単に使えますねこれ。 素晴らしい、です。 おかげでbotnetのC&C server等でも広く使われるようになったとかってことですが。

ともあれ、 日本語の要諦サイトLet's Encrypt 総合ポータルもあり、 だいぶわかりやすくなってます。

基本的には、

  1. certbot-autogit又はwget https://dl.eff.org/certbot-autoで取得
  2. 認証原理は、
    1. certbot-autoがLet's Encrypt側から指定されたhttp://.../.well-known/XXXXXXにfileを作る
    2. Let's Encrypt側がそのfileをGET、認証
  3. なのでstandalone(certbot-autoが臨時のhttp serverを建て、Let's Encryptからのrequestを受ける)が基本
  4. その間本来のWWW serverを止めねばならないが、止めたくない時は「--webroot」でDocumentRootを指定し、certbot-autoにfileを作らせる
  5. 初回の(というか最後に成功した)command optionsを/etc/letsencrypt/以下に保存しておき、次回以降「renew」commandでは省略可
  6. renewを付けて走らせても、証明書期限が30日を切っていないと発動しない(無理やり更新するには--force-renew optionが必要)
  7. --post-hookも指定して、apacheのreloadを自動化(これはrenewが走らないと発動しない。単純にrenewの終了status codeだと0になるので「&&」で繋ぐだけでは判別不能だった)
  8. 証明書取得がうまく行くと、/etc/letsencrypt/live/someserver.co.jp/以下に各種cert filesのsymbolic linkが作成されるので、/etc/apache2/site-enabled/default-ssl中でSSLCertificateFile等の示す先をここのcert.pem等にする(Apache2.4以上やnginxなら証明書+中間CA証明書にfullchain.pemが使える)

こちとら、apache2 serverを止めたくない状況だったので、

1
$ sudo cerbot-auto certonly --webroot -w /var/www/ -m support@company.co.jp -d someserver.co.jp --agree-tos

(-w: webroot-path, -d: domain, -m: mail address)

更新は、/etc/cron.daily/certbotを作って、

1
2
#!/bin/sh
cerbot-auto renew -q --post-hook 'service apache2 reload'

で良さそうです。sudo chmod a+x /etc/cron.daily/certbotを忘れずに。

certbot-autoは、実行するといきなりapt-get updateしてからpython2.7とか入れるのと幾つかのpackagesをupdateするので注意です。

また、Let's EncryptにしてからSSL Server Testをかけてみると、「Incorrect SNI alerts」というのが出るようになりました。 これは、/etc/apache2/site-enabled/default-ssl<VirtualHost _default_:443>ServerName XXXXXXとすることで解決しました。 cf. SSLテストで”Incorrect SNI alerts”を解決する

command log

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
wget https://dl.eff.org/certbot-auto
chmod a+x certbot-auto
sudo chown root:root certbot-auto
sudo mv -i certbot-auto /usr/local/bin/
sudo certbot-auto certonly --webroot -w /var/lib/tomcat7/webapps/ROOT/ -m ls-support@jmtech.co.jp -d cx4.locationsupporter.info --agree-tos
sudo vi /etc/apache2/sites-enabled/default-ssl
================================================
	SSLCertificateFile /etc/letsencrypt/live/cx4.locationsupporter.info/cert.pem
	SSLCertificateKeyFile /etc/letsencrypt/live/cx4.locationsupporter.info/privkey.pem
	SSLCertificateChainFile /etc/letsencrypt/live/cx4.locationsupporter.info/chain.pem
================================================
echo '#!/bin/sh' > certbot
echo "cerbot-auto renew -q --post-hook 'service apache2 reload'" >> certbot
chmod a+x certbot
sudo chown root:root certbot
sudo mv -i certbot /etc/cron.daily/