自堕落な技術者の日記

基本は喰ってるか飲んでるかですが、よく趣味でカラオケ・PKI・署名・認証・プログラミング・情報セキュリティをやっています。旅好き。テレビ好きで芸能通

プログラミング

Chrome 39安定版のリリースと、有効期限が2017年1月以降のSHA1証明書の警告表示

なかなか確認ができなかったんですが、 Chrome 39安定版が2014年11月18日にリリースされて、 例のChromeのSHA1証明書の表示変更が、 反映されていたのではと、確認しました。

そういえば、大量のHTTPSサイトのリストがあったからそれで調べてみるべぇといろいろ、 探してみたんですがなかなか見つからず、秋山さんから2つほどサイトを紹介頂いて 確認できました。

国内サイトなのでクレームが来たらアレなので、サイト名は今回はご勘弁頂きたいんですが、 早速 Chrome 39 安定版でそのサイトを表示してみると、確かに予告されていた通り、 SSLサーバー証明書の有効期限が2017年1月以降のHTTPSサイトを表示させると、 「secure, but with minor erros」の黄色三角の表示になりました。
013 014

メッセージはHTTPSとHTTPのコンテンツ混在の場合と違って以下のように表示されます。

このサイトでは古いセキュリティ設定が使用されており、 Chromeの今後のバージョンではこのサイトに安全にアクセスできない 可能性があります。

問題対象となるサイトを探すのは大変

読者のみなさんにも試してもらえるように、当たり障りのなさそうな海外の 問題条件にあてはまるサイトを探してみたんですが、なかなか見つかりませんでした。 HTTPSサイトの膨大なリストはゲットできたんですが、そこから条件にあう サイトを見つけるのが結構手間で、

  • とりあえず、有効期限が2017年〜2018年あたりのもの。 それ以上だとテスト用のプライベート証明書が多いので。
  • と、フィルタリングをしても、繋がらないサイトや、 プライベートCAのサイト、SHA2証明書のサイトなどが になってしまます。
ちょっとプログラム書いて、この手の事が簡単に調査できるようにしたいです。 無難なサイトが見つかったらこの記事を更新して、紹介しようと思います。 iPhone版、Android版、Mac OS X版のChromeも対応がまだのようですね。

今日はこの辺で

関連記事・リンク

(小ネタ) MacPortsのpythonのbsddbモジュールロードエラーの回避方法

みなさま、ゴールデンウィーク中如何お過ごしでしょうか。 近々、Bitcoinの技術的なお話をさせて頂くことになり、ゴールデンウィークもプログラミングして試したり資料書いたりしております。

さて、PythonのBitcoin用便利ツール "bitcointools" を使っていろいろ試していたんですが、Mac OS Xで動いているbitcoindのローカルにあるブロックデータでも見てみようかと "dbdump.py" を動かしてみようとするもエラー発生。bitcoind のブロックデータはBerkley DB形式で保存してるんですが、Mac OS X MacPortsのPython ではそのライブラリを読もうとするとエラーになるみたいなんです。

$ python
Python 2.7.5 (default, Aug 25 2013, 00:04:04)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import bsddb
Traceback (most recent call last):
File " File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/bsddb/__init__.py", line 67, in import _bsddb
ImportError: No module named _bsddb
>>>
グーグル先生に聞いてみたところ みなさんも同様に悩んでおられる様子

ActivePython 2.7にある"_bsddb.so" を MacPortsにコピーすれば動くみたいな話が書いてあったので試してみたら動きました。

まずは、ActivePythonをサイトからダウンロードしてインストールします。

MacPorts PythonとActivePythonではインストール先が違います。

ActivePython for Mac OS Xのインストール先
/Library/Frameworks/Python.framework/Versions/2.7
MacPorts の Pythonのインストール先
/System/Library/Frameworks/Python.framework/Versions/2.x (いろいろ)
インストールしたら早速ファイルコピーします。
% cd /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7
% sudo cp -i lib-dynload/_bsddb.so /System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/
これで MacPorts Pythonでも無事 bsddb が使えるようになりました。
$ python
Python 2.7.5 (default, Aug 25 2013, 00:04:04)
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import bsddb
>>>
今日はこんなところで。

Android SDK 19だかJSONだかAdMobだかzipalignだかでハマった話

熱があって体調激悪ですが、なんか書いてみましたの第二弾です。

週末、自前のAndroidアプリの 手直しをしようとしててハマったので愚痴だと思って聞いてください。

Root CA Viewer Liteに証明書リストをエクスポートする機能を追加しようと思い、 幾つかのサイトを参考にしながら、でも、Android のプログラミングも超久しぶりなので ビルドどうやんだっけ?、コード署名どうやんだっけ?などもたもたしながら 2時間ほどで実機で動作することは確認できました。

実機確認はGoogle PlayにあげずにLAN内でやるわけですが、 AirDroidは すごく助かりますね。これをあげるとAndroid側がリモートサーバーになって 開発機からapkをアップしたり、SDカードみたりいろんなことができて実機テストが捗ります。

まず、zipalignでハマる

で、まぁ動いたから公開すんべぇとGoogle Playにアップしようとしたら zipalignされてないからアップロードできないと英語で怒られました。

minghaiさんの日記:apkファイルを最適化する zipalign
に説明があった。apkファイルがzipalignされてないとapk(zip)解凍の時、非常に メモリ効率が悪くなるのだそうです。

探してみるも zipalign などない。どうやら新しい Android SDK でないと 入っていないそうです。仕方ないのでAndroid SDK Managerで アップデートをかけました。Android 4.0.3 API 15 までしか入ってなかったんですが、 Android 4.4 API 19 まで上げてみます。APIのターゲットは15のままです。 ただし、Google AdMobは、コード手直ししないといけなそうだったりしたので、これだけ保留にしておきました。

で、アップデートすると、「そもそもEclipseのライブラリが古いよ」とこれまた 英語で怒られてヘコみます。これは従順に言われた通りに上げます。

参照関係に泣く

で、Root CA Viewerをリビルド、エミュレータで実行させようとすると、リビルドできない。

Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
その他にも、DEXが壊れててよめねーじゃねーかと英語で怒られます。 Eclipseのログ見ろっていってもログの場所がわからない。

Google大先生に聞いてみるとEclipseのログは $WORKSPACE/.metadata/.logにあることがわかりました。 ログにはあまり参考になりそうな情報はありませんでしたが、 多分、参照関係がおかしくなっているんでしょうね。 Google AdMobが古いせいなのかなと思い、AdMobライブラリも新しくしてみました。 一部、ソースコードやらXML設定ファイルやらを手直しして再度ビルドします。

再度ビルドしてみようとすると、

com.google.ads.AdView failed to instantiate. java.lang.ClassNotFoundException: org.json.JSONException at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
と怒られます。ええーーっ、JSON入ってないの?使っているJDKが古いのか、 Androidのライブラリが古いんでしょうねぇ。 Google大先生にJSONの件を聞いたら このページ(NoClassDefFoundError when trying to unit test JSON parsing in Android)を返してくれました。 APIのターゲットを上げると4.0そこそこのやつでは 動かなくなりそうだったので、org.jsonのソース探して、jar作って 置いてみました。

すると、またコレが出るようになりました。

Unable to execute dex: java.nio.BufferOverflowException. Check the Eclipse log for stack trace.
結局解決してなかったのね。

随分調べて このページ(Issue 61710:java.nio.BufferOverflowException When Building with 19 Build Tools) を見つけました。どうやらAndroid SDK 19 Build Toolの問題らしく、

  1. Android 19 Build Tools, API 19を削除する
  2. Target SDK を19から18に戻す
  3. extras/android/support/v7/appcompat/libs/android-support-v4.jarの参照を削除する
  4. 再度 android-support-v4.jar を追加する
なんか、書かれた通りにうまく行かない事もあったんですが、Eclipseを再起動したり、プロジェクトを閉じたり、開いたりしている うちに、書かれた方法で無事ビルドでき、動作するところまではこぎつけました。

最後にzipalignではまる

結局は署名済apkが出力される場所が間違っていたというオチなわけですが、 本来なら署名済apkを作った際に自動的にzipalignも実行されるとの事です。 結局コマンドラインでやってしまいました。

% tools/zipalign 4 RootCAViewerLite.apk RootCAViewerLite_.apk (*_.apkが出力先で署名済)
% tools/zipallgn -v -c RootCAViewerLite_.apk (チェック)
Verifying alignment of RootCAViewerLite.apk (4)...
62 res/layout/activity_cert.xml (OK - compressed)
655 res/layout/activity_main.xml (OK - compressed)
1252 res/layout/activity_textview.xml (OK - compressed)
1937 res/menu/activity_cert.xml (OK - compressed)
2256 res/menu/activity_main.xml (OK - compressed)
2604 res/menu/activity_textview.xml (OK - compressed)
2916 AndroidManifest.xml (OK - compressed)
4000 resources.arsc (OK)
7316 res/drawable-hdpi/ic_action_search.png (OK)
7788 res/drawable-hdpi/ic_launcher.png (OK)
9864 res/drawable-ldpi/ic_launcher.png (OK)
11236 res/drawable-mdpi/ic_action_search.png (OK)
11612 res/drawable-mdpi/ic_launcher.png (OK)
13272 res/drawable-xhdpi/ic_action_search.png (OK)
13828 res/drawable-xhdpi/ic_launcher.png (OK)
16458 classes.dex (OK - compressed)
570061 README (OK - compressed)
571082 jsr305_annotations/Jsr305_annotations.gwt.xml (OK - compressed)
571300 jsr305_annotations/v0_r47/V0_r47.gwt.xml (OK - compressed)
571474 META-INF/MANIFEST.MF (OK - compressed)
572232 META-INF/CERT.SF (OK - compressed)
573041 META-INF/CERT.RSA (OK - compressed)
Verification succesful
ファイルサイズが昇順になるんですね。というわけで、いろいろありましたが何とか新しいRoot CA Viewer Liteを 公開することができました。あーつかれた。

W3C XML暗号化の脆弱性に対するW3Cのコメントに「ちょっとなぁ」と思った件

2011年10月17日より米国シカゴで開催された国際会議 "18th ACM Conference on Computer and Communications Security" において、 Tibor Jager と Juraj Somorovsky により "How to Break XML Encryption" という発表がありました。 W3C勧告であるXML文書の暗号化の標準 "XML Encryption Syntax and Processing, 10 Dec 2002" においてAESでも3DESでもCBC(Cipher Block Chaining)モードを 使っている限り解読される可能性があるというものです。

これに対しW3Cは "Some notes on the recent XML Encryption attack" というコメントを発表しました。

これはぶっちゃけちゃうと「CBC使わずにGCM(Galois Counter Mode)なんかを使ってね。 標準にもなってるしね。」という内容なんですが、 標準になっているといってもOPTIONALですよね。

引用:W3C XMLEnc 5.2.4 AES-GCM
- http://www.w3.org/2009/xmlenc11#aes128-gcm (OPTIONAL)
- http://www.w3.org/2009/xmlenc11#aes256-gcm (OPTIONAL)
AES-GCMをサポートするXML暗号化ライブラリなんてあるのかと ちょっと調べてみました。

手軽に手に入りやすそうな比較的メジャーなJava XML暗号ライブラリというと こんなところかと思います。

Sun/Oracle JavaのXMLはXML署名しか含まれていません。 サポートするアルゴリズム情報をApache, IAIKで見てみましたが AES-GCMはサポートされていないようです。 IBM Java SDKについても検索してみましたが、どうやらGCMはサポートしていないようです。 Javaでこれだけダメなんだから、他の言語用のライブラリはもっと ひどいはず。Microsoft .NETについてもGCM必須なSuite-B対応が進んでいるので もしやとおもいましたが、どうやらダメなようです。

結局、W3Cは「GCM使えばいいじゃん」というものの「使えそうな実装がない」 という、何ともとほほな状況であることがわかりました。 自前でAES-GCM対応するしかないですかね。

祝 Java SE 7 リリース記念(第2弾)「証明書検証の弱いアルゴリズムの制限機能」

Java SE 7のSecurity Enhancementsには

CertPath Algorithm Disabling
Weak cryptographic algorithms can now be disabled. For example, the MD2 digest algorithm is no longer considered secure. The Java SE 7 release provides a mechanism for denying the use of specific algorithms in certification path processing and TLS handshaking. See Appendix D: Disabling Cryptographic Algorithms in Java PKI Programmer's Guide and Disabled Cryptographic Algorithms in Java Secure Socket Extension (JSSE) Reference Guide for more information.
と書いてあります。なるなる。証明書の検証において弱い暗号アルゴリズムを使わないように設定することができ、これはSSL/TLSの場合でも同様に設定できるようです。今日はこのアルゴリズム無効化について説明したいと思います。

プロパティファイル java.security の違い

Java SE 6 と7では若干$JRE_HOME/lib/security/java.securityのファイルの内容が違うんですが、 大きく追加されているのは3点あります。

  • Policy for failed Kerberos KDC lookups - Kerberosの設定
  • Algorithm restrictions for certification path (CertPath) processing - (証明書の)認証パス検証処理のアルゴリズム制限
  • Algorithm restrictions for Secure Socket Layer/Transport Layer Security (SSL/TLS) processing - SSL/TLS処理のアルゴリズム制限
一般の証明書検証とSSL/TLSでの証明書検証とで分けてアルゴリズムに制限をかけることができるようです。 ちなみに一般の証明書検証ではデフォルトは
jdk.certpath.disabledAlgorithms=MD2
になっており、MD2アルゴリズムは無効になるよう設定されています。SSL/TLSでは
jdk.tls.disabledAlgorithms
のプロパティで設定するようになっていますが、SSL/TLSにおいては無効設定は無いようです。

アルゴリズムの無効化の指定方法

指定するのは署名アルゴリズムではなく、ハッシュアルゴリズムと公開鍵暗号のアルゴリズムで、 公開鍵暗号のアルゴリズムについては、鍵長を指定できます。以下に幾つか設定の例を示します。
# MD2を無効化(デフォルト)
jdk.certpath.disabledAlgorithms=MD2
# MD2, SHA1, DSA, ECDSAを無効化
jdk.certpath.disabledAlgorithms=MD2, SHA1, DSA, ECDSA
# MD2, SHA1 を無効とし、鍵長2048bit未満のRSAを無効
jdk.certpath.disabledAlgorithms=MD2, SHA1, RSA keySize < 2048
RIPEMD-160等のSun(Oracle)提供の暗号アルゴリズムにないものを指定できるのかは 気になるところです。時間が取れたら見てみます。

プログラムの中でアルゴリズム制限を指定する

上記のようにプロパティファイルで指定することもできますが、 プログラムの中でも動的に指定することも可能です。

import java.security.Security;
・・・
Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2, MD5, DSA");

で、実際に使ってみた

試しにRSAの鍵長を可変にして、どうなるか試してみました。

# jdk.certpath.disabledAlgorithms=RSA keySize < 1024 -- RSA1024bit未満を禁止
→検証成功
# jdk.certpath.disabledAlgorithms=RSA keySize < 2048 -- RSA2048bit未満を禁止
→unable to find valid certification path to requested target
う〜ん、確かにプロパティの変更によって検証結果は変わりますが、 例外のメッセージは全くアルゴリズム理由でそうなったのか わからないようになっちゃってますね。

仕方ないのでデバックメッセージを表示するようにして (java -Djava.security.debug=all) メッセージを見てみるとアルゴリズムを禁止した場合と鍵長を制限した 場合とでメッセージが異なるみたいです。

# jdk.certpath.disabledAlgorithms=RSA -- RSAを禁止してみた場合
algorithm check failed: SHA1withRSA disabled
# jdk.certpath.disabledAlgorithms=RSA keySize < 2048 -- RSA2048bit未満を禁止
algorihtm constraints check failed

暗号アルゴリズムの危殆化情報の管理と自動処理

暗号アルゴリズムは時代の変遷とともに脆弱になり、推奨されない暗号の鍵長もまた 変わっていきます。特に過去の電子署名ファイルや暗号化されたファイルで 使われている暗号アルゴリズムが当時大丈夫だったのかは気になるところです。 「 RFC 5698 Data Structure for the Security Suitability of Cryptographic Algorithms (DSSC)」というデータフォーマットがありますが、これは、 は、 どの暗号アルゴリズムや鍵長が何時の時代に、どのくらいの期間までは安全とされていたかを規定することができるデータフォーマットです。

現在、DES、MD5、SHA1、鍵長の短いRSAなど暗号アルゴリズムの危殆化が話題になっていますが、どのアルゴリズムが何年から何年頃までは使い物になったのかをNIST、CRYPTRECなど暗号アルゴリズムの公的な評価機関がDSSCのような電子データの形式として公開、発行して頂けると、このデータを検証ポリシーとして使用し、過去のあるデータが「当時安全とされていた暗号アルゴリズム(や鍵長)」を使っていたかを自動的に判定できるようになります。

DSSCの内容により自動的にjdk.certpath.disabledAlgorithmsに反映させて検証するなんてこともできますね。

おわりに

今日はJava SE 7で新たに提供されることになった証明書検証における弱い暗号アルゴリズムの制限機能について紹介しました。 これまでに、暗号スイートのレベルで制限することはできましたが、ハッシュや公開鍵暗号アルゴリズム、鍵長のレベルでミドルウェアで制限が加えられる汎用の製品はJava SE 7が初めてなのではないかと思います。 SSL/TLSにも使えるので、そろそろ "jdk.tls.disabledAlgorithms=MD2" などとしてもいい頃ですよね。

やべやべ、会社は夏休みなんだけど明日から一週間休日出勤だ。風呂入って寝よう。ではでは。

関連記事>

祝 Java SE 7 リリース記念「JCEはどうなってんの?」

大変ご無沙汰しております。もはやセキュリティ技術者とはいえない状態でわけのわからない仕事に忙殺されております。さて、今日は Java の話題です。Java SE 6のリリースが2006年12月でしたから、かれこれ5年、ようやく2011年7月28日 Java SE 7 がリリースされました。今日は「祝 Java SE 7 リリース記念」ということで暗号、セキュリティ、SSL/TLSの部分を中心に変更点を見ていこうと思います。

早速ダウンロード

7月28日になって何度もダウンロードページを訪れていたんですが、日本時間で夜の10時か11時頃にようやくダウンロードできるようになっていたみたいです。バージョンを見るとこんな感じ、、、

% java -version
java version "1.7.0"
Java(TM) SE Runtime Environment (build 1.7.0-b147)
Java HotSpot(TM) Client VM (build 21.0-b17, mixed mode, sharing)
一昨日、Java SE 7 Preview Release b147 というのを落としたんですが、内容的には同じもののようです。

サポートするJCEプロバイダの差分をみてみましょう

Java SE 7 で変更点のひとつの目玉は楕円暗号のサポートなんだそうです。 Java SE 6 と Java SE 7(b147) でJCE(Java Cryptographic Extension)プロバイダの提供物の違いをdiffを取ってつらつら眺めてみました。 全体的にsun実装の内部パッケージ名がcom.sun.net.ssl.internalからsun.securityに変更になっているようです。

Java SE 6Java SE 7(b147)
SUN 1.6SUN 1.7
CertStore.LDAPのパッケージ名が変更になっただけ
SunRsaSign 1.6SunRsaSign 1.7
バージョン変更のみ
なしSunEC 1.7
楕円暗号のプロバイダが新規提供
SunJSSE 1.6SunJSSE 1.7
TLSv1.1、TLSv1.2の新規提供。内部パッケージ名の変更
SunJCE 1.6SunJCE 1.7
KeyGeneratorでSunTls12Prfの新規提供
SunJGSS 1.0SunJGSS 1.7
バージョン変更のみ
SunSASL 1.5SunSASL 1.7
SASLプロバイダ。NTLM認証の新規提供
XMLDSig 1.6XMLDSig 1.7
XML署名。W3C Canonical XML 1.1の新規サポート
SunPCSC 1.6SunPCSC 1.7
バージョン変更のみ
SunMSCAPI 1.6SunMSCAPI 1.7
Windows版のみ提供のMS CAPIを使ったプロバイダ。 SignatureでNONEwithRSA、SHA256withRSA、SHA384withRSA、SHA512withRSAの 新規サポート
XML正規化1.1(Canonical XML 1.1)をサポートしたのは個人的にはちょっと嬉しいかもしんない。SunSASLのNTLM認証もいろいろ遊べそうですね。SunSASLについてはここにサポートアルゴリズムが書いてあるんですが、そこにはNTLMについて触れてません。しかしながらSunSASLプロバイダのinfoを見てみるとこんな感じになってます。
Sun SASL provider(implements client mechanisms for: DIGEST-MD5, GSSAPI, EXTERNAL, PLAIN, CRAM-MD5, NTLM; server mechanisms for: DIGEST-MD5, GSSAPI, CRAM-MD5, NTLM)
どっちが正しいんでしょうね?時間のあるときみてみようと思います。

楕円暗号(Elliptic Curve Cryptography)のサポート

Java SE 7になってようやく楕円暗号のためのJCEプロバイダであるSunECが新たに提供されるようになりました。ECDH、ECDSAをサポートしておりSSL/TLSや署名なんかにちゃんと使えます。 署名アルゴリズムについては以下をサポートしています。

SunECでサポートする署名アルゴリズム
NONEwithECDSA
SHA1withECDSA
SHA256withECDSA
SHA384withECDSA
SHA512withECDSA
サポートしている楕円曲線の名前は以下の通りです。かなりの数サポートしていますね。カスタム定義した曲線の利用が可能なのかは時間があるとき調べてみたいと思います。
曲線名オブジェクト識別子
secp112r11.3.132.0.6
secp112r21.3.132.0.7
secp128r11.3.132.0.28
secp128r21.3.132.0.29
secp160k11.3.132.0.9
secp160r11.3.132.0.8
secp160r21.3.132.0.30
secp192k11.3.132.0.31
secp192r1,NIST P-192,X9.62 prime192v11.2.840.10045.3.1.1
secp224k11.3.132.0.32
secp224r1,NIST P-2241.3.132.0.33
secp256k11.3.132.0.10
secp256r1,NIST P-256,X9.62 prime256v11.2.840.10045.3.1.7
secp384r1,NIST P-3841.3.132.0.34
secp521r1,NIST P-5211.3.132.0.35
X9.62 prime192v21.2.840.10045.3.1.2
X9.62 prime192v31.2.840.10045.3.1.3
X9.62 prime239v11.2.840.10045.3.1.4
X9.62 prime239v21.2.840.10045.3.1.5
X9.62 prime239v31.2.840.10045.3.1.6
sect113r11.3.132.0.4
sect113r21.3.132.0.5
sect131r11.3.132.0.22
sect131r21.3.132.0.23
sect163k1,NIST K-1631.3.132.0.1
sect163r11.3.132.0.2
sect163r2,NIST B-1631.3.132.0.15
sect193r11.3.132.0.24
sect193r21.3.132.0.25
sect233k1,NIST K-2331.3.132.0.26
sect233r1,NIST B-2331.3.132.0.27
sect239k11.3.132.0.3
sect283k1,NIST K-2831.3.132.0.16
sect283r1,NIST B-2831.3.132.0.17
sect409k1,NIST K-4091.3.132.0.36
sect409r1,NIST B-4091.3.132.0.37
sect571k1,NIST K-5711.3.132.0.38
sect571r1,NIST B-5711.3.132.0.39
X9.62c2tnb191v11.2.840.10045.3.0.5
X9.62 c2tnb191v21.2.840.10045.3.0.6
X9.62 c2tnb191v31.2.840.10045.3.0.7
X9.62 c2tnb239v11.2.840.10045.3.0.11
X9.62 c2tnb239v21.2.840.10045.3.0.12
X9.62 c2tnb239v31.2.840.10045.3.0.13
X9.62 c2tnb359v11.2.840.10045.3.0.18
X9.62 c2tnb431r11.2.840.10045.3.0.20
Java SE 7のSunJSSEプロバイダでサポートしているCipherSuitesのリストはここにありますが、その中で楕円系のCipherSuitesはこんな感じ、、、かなりの数ですね。メンテしている環境別のCipherSuitesサポート状況のテーブルは、近いうちJava SE 7を含め歴代Javaのサポート状況を追記したいと思っています。
Java SE 7 SunJSSEプロバイダの提供する楕円系CipherSuites
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
TLS_ECDHE_RSA_WITH_RC4_128_SHA
TLS_ECDH_ECDSA_WITH_RC4_128_SHA
TLS_ECDH_RSA_WITH_RC4_128_SHA
TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
次に簡単なHTTPSクライアントを書いてTLSのelliptic_curves extensionに何が設定されているか、パケットキャプチャして調べてみました所、下のような感じになっていました。げげっ25個もサポートされています。多すぎです。IEやFireFoxでは確か3つぐらいだったはず。
TLS elliptic_curves拡張にある曲線名
secp256r1
sect163k1
sect163r2
secp192r1
secp224r1
sect233k1
sect233r1
sect283k1
secp384r1
sect409k1
sect409r1
secp521r1
sect571k1
sect571r1
secp160k1
secp160r1
secp160r2
sect163r1
secp192k1
sect193r1
sect193r2
secp224k1
sect239k1
secp256k1

その他気になった変更点

セキュリティ関係の変更点はここにまとめらているんですが、その中で気になったところをかいつまんで紹介したいと思います。

JSSE(SSL/TLS), TLS 1.1, TLS 1.2
TLSv1.1, TLSv1.2 がサポートされるようになりました。
JSSE(SSL/TLS) Connection-sensitive trust management
SSL/TLSで使われるアルゴリズムを署名アルゴリズム等弱い物を使わない等指定できるようです。 証明書の中のアルゴリズムまで制限できるのか気になるところ。
JSSE(SSL/TLS) Endpoint verification
HostnameVerifier()を定義すれば、 SSL/TLSのホストの一致確認方法を実装側で 制御できるようです。逆にホスト名をチェックしないこともできたり、証明書のへんなところに入っている ホスト名であっても認証できるようにしたりできますね。
JSSE(SSL/TLS) TLS renegotiation
2009年3月に発表されたSSL rebindingやSSL renegotiationといわれるSSL/TLSの仕様の欠陥をついた攻撃を防ぐためのTLS renegotiation拡張をサポートしているそうだ。
JSSE(SSL/TLS) Server Name Indication (SNI) for JSSE client
SNI拡張がサポートされた。確かにパケットキャプチャするとClientHelloに入っている。一台のウェブサーバーで複数のバーチャルホストに対してちゃんとHTTPS接続することができるようになります。これはテスト目的で前から非常に欲しかった機能。

以上、Java SE 7 リリース記念ということで、JCE関連の機能の変更点をみてみました。やべやべ、もう寝ないとorz

参考リンク

関連記事>

変更履歴

  • 2011-07-31 参考リンクにおいてリンク切れを修正、JCA、PKIを追加

Apache HarmonyのJSSE(Java Secure Socket Extension)

JavaでSSL/TLS通信をしたい時に通常はJSSE(Java Secure Socket Extension)という仕組み使うんですが、これ使えば、実装色々切り替えたり、追加したりなんてことができます。Apache Tomcat(+Sun Java JSSE)だとCamellia系のCipherSuitesに対応してないそうで、何か対応してるもの、追加で対応できそうなものを調べてみました。

Sun Javaで使えるJSSEってあんまり選択肢がないのね

下の例のようにJSSEプロバイダ名を指定することによりJSSEを切り替えればいろんなSSLエンジンを試せるわけですが、

SSLContext ctx = SSLContext.getInstance(アルゴリズム名, プロバイダ名);
SSLContext ctx = SSLContext.getInstance("SSL", "SunJSSE");
SSLContext ctx = SSLContext.getInstance("TLS", "HarmonyJSSE");
Sun Javaで使えそうなJSSEの選択肢って少ないんだなぁってことが調査してみるとわかりました。Sun Javaで使えそうなのは標準品を含めて以下の3つぐらいしかなさそう。 暗号アルゴリズム系のためのJCE対応のライブラリは潤沢にある中、JSSEの方は選択肢がすくないですね。

なんか調べてみるとJSSEはJava VMに依存している方が多いんじゃないかって 感じがします。

新しいCipher Suitesを追加したいと思ったら、Sun Java用にJSSEを書き起こすっていう 手もありですが、コード署名しないと何かと面倒なのでおススメではありません。 JESSIEでやろうとするとGNU classpathなんでちょっとなぁ、、、と。JESSIE自体、 あんまりメンテナンスしてないみたいだし。 で、最終的にApache Harmonyを調べてみるのがいいのかな、、と思ったわけです。 Apache HarmonyはオープンソースでフリーなJavaの実装だそうです。

Apache HarmonyとTomcatを試してみる

Apahce HarmonyのSSL/TLSの機能というか、JSSEの機能は暗号ライブラリとしてBouncyCastle JCE Libraryを使用しており、SunJCEは使えません。 従ってHTTPSのためのSSLサーバー証明書と鍵はJKS形式はSun独自の形式なので使えなくてBouncyCastle JCEがサポートしている PKCS#12かBKS(BouncyCastle Key Store)形式を使う必要があります。 ただ、OpenSSLで生成したPKCS#12でやってみたところMacエラーだったりで読み込めず BKSを使うのがよいのかもしれません。 JKSからBKSへの変換ツールは「ここ」に置いてみたので使ってみてください。

conf/server.xmlファイルにはこんな感じでkeystoreFile、keystorePass 、keystoreTypeを設定します。

<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
 maxThreads="150" scheme="https" secure="true"
 clientAuth="false" sslProtocol="TLS"
 keystoreFile="conf/zzz.bks"
 keystorePass="changeit"
 keystoreType="BKS" />

あとはbin/catalina.batに以下のようなパス設定をしとけばApache Tomcat + Apache Harmonyは動くと思います。
set CATALINA_HOME=C:\Java\apache-tomcat-6.0.30-wharmony
set JAVA_HOME=C:\harmony-6.0-jdk-991881
set JRE_HOME=C:\harmony-6.0-jdk-991881\jre
ウェブブラウザ等でHTTPSでつなぐことはできたでしょうか?

で、OpenSSLで繋いでみる

openssl s_client機能を使ってApache Tomcat + Harmonyのサーバーに接続してみましょう。

% openssl s_client -host zzz.com -port 8443
CONNECTED(00000003)
depth=1 /C=JP/O=HOGE
verify error:num=19:self signed certificate in certificate chain
verify return:0
14052:error:04077068:rsa routines:RSA_verify:bad signature:rsa_sign.c:209:
14052:error:1408D07B:SSL routines:SSL3_GET_KEY_EXCHANGE:bad signature:s3_clnt.c:1447:
とJava実装やブラウザだと出てこないエラーが出てきてしまいました。ググってみるに-cipherを設定しないことが 原因のようで-cipher 'ALL:!kEDH'を指定してちょっと絞り込みをしないといけないそうです。
% openssl s_client -host zzz.com -port 8443 -cipher 'ALL:!kEDH'
CONNECTED(00000003)
中略
depth=1 /C=JP/O=HOGE
verify error:num=19:self signed certificate in certificate chain
verify return:0
read R BLOCK
DONE
これでApache Tomcat + HarmonyにOpenSSL s_clientで繋ぐことができるようになりました。

Apache HarmonyのJSSEのコード

Apache HarmonyのJSSEはjre/lib/boot/x-net{.jar,-src.jar}にある org.apache.harmony.xnet.provider.jsse パッケージがそれに当たります。 x-net.jar自体はコード署名されてないようなので、 CipherSuiteを追加し放題で x-net.jarに入れ替えても動きそうな雰囲気です。

JSSEプロバイダの定義はJSSEProvider.javaにあります。 コメントのところに割と詳しい説明があって以下のようなものが書かれています。

  • サポートしているCipherSuites:別表
  • 使用する共通鍵暗号アルゴリズム:IDEA,RC2,RC4,DES,3DES
  • 使用するMacアルゴリズム:MD5, SHA-1
  • 使用する鍵交換アルゴリズム: RSA, DH, DHE
Apache Harmony 6.0 build 991881のHarmonyJSSEプロバイダーで提供されているアルゴリズムとその値の一覧は以下の通りのようです。
SSLContext = TLS(=TLSv1)
KeyManagementFactory = X509
TrustManagementFactory = X509
HarmonyJSSEがサポートしているCipherSuiteの一覧は以下の通りです。
TLS_NULL_WITH_NULL_NULL
TLS_RSA_WITH_NULL_MD5
TLS_RSA_WITH_NULL_SHA
TLS_RSA_EXPORT_WITH_RC4_40_MD5
TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
TLS_RSA_WITH_IDEA_CBC_SHA
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_DSS_WITH_DES_CBC_SHA
TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_RSA_WITH_DES_CBC_SHA
TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_DSS_WITH_DES_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_RSA_WITH_DES_CBC_SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
TLS_DH_anon_WITH_RC4_128_MD5
TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
TLS_DH_anon_WITH_DES_CBC_SHA
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
そして、そのうちデフォルトの設定で提供するCipherSuiteは以下の通りです。
TLS_RSA_WITH_RC4_128_MD5
TLS_RSA_WITH_RC4_128_SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
TLS_RSA_WITH_DES_CBC_SHA
TLS_DHE_RSA_WITH_DES_CBC_SHA
TLS_DHE_DSS_WITH_DES_CBC_SHA
TLS_RSA_EXPORT_WITH_RC4_40_MD5
TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
今晩はこんなところで、、、
ではでは

GoogleのコマンドラインツールGoogleCLをcygwinで試してみたゾ

GoogleからカレンダーやらDocsやらがコマンドラインから操作できるオープンソースのツールGoogleCLがリリースされたそうで、ちょっとcygwinでできるか試してみました。Pythonで実装されているというのもソソるじゃないですか。

cygwinでのインストール

  1. cygwin で python パッケージを入れておく
  2. 入ってなければgdata-python-clientをインストール
    % tar xvfz gata-2.0.10.tar.gz
    % cd gdata-2.0.10
    % python setup.py install
  3. googlecl をインストール
    % tar xvfz googlecl-0.9.7.tar.gz
    % cd googlecl-0.9.7
    % python setup.py install

使ってみる

インストールは難なくできたんで、早速使ってみます。初回、何かのコマンドを使おうとするとブラウザで「次のURLにアクセスしなさい」みたいなのが出てきてGoogleのアカウントで認証してGoogleCLで使えるようにするか聞いてきて、OAuthの認証トークンなんかの設定情報が~/.googleclディレクトリに保存されるようです。自動ログイン設定までの流れはこんな感じ、、、

Did not find config / preferences file at ~/.googlecl/config ...
making one.
Please specify user: Googleアカウント名
Please log in and/or grant access via your browser at
Failed to launch web browser: could not locate runnable browser
Please log in and/or grant access via your browser at
https://www.google.com/accounts/OAuthAuthorizeToken?oauth_token=...
then hit enter.
すると初回のgoogle docs listコマンドの結果が表示されます。

コマンド例

結果はUTF8で表示されちゃうのでLANGの設定に気を付けます。 例えば、こんな感じです、、、

% export LANG=ja_JP.UTF8
% google docs list
文書1, http...
文書2, http...


% google calendar title,when --date 2010-01-01,2010-04-01
あそび, Jan 04 00:00 - Jan 05 00:00
あそび2, Jan 10 00:00 - Jan 11 00:00
カレンダーの情報なんかをコマンドラインで得られるのは結構うれしいかもしれません。

参考リンク

Ruby1.9+OpenSSL for Winで大いにハマるの巻

不幸への序章

OpenSSLを使ったプログラミングを簡単にできると評判のスクリプト言語Rubyを勉強してみようかなぁと思いまして、インストールを決意しました。環境は手軽に書けるのでWindows XP上でWindowsネイティブの最新版がいいかなぁ、、、と思い「Ruby入門勉強ルームさんのRuby1.9.1のWindows環境へのインストール」を参考に簡単にインストールはできちゃいました。初心者のHello World的なものは動いていたのでまぁ、この時点では安心していたわけです。

証明書作れないんですけど、、、

まぁ、手始めにオレオレX.509証明書でも作ってみるべぇと、

require 'openssl'
cert = OpenSSL::X509::Certificate.new
:中略
cert.not_before = Time.now
cert.not_after = Time.now
:以下略
みたいな感じで動かしてみるに
% ruby z2.rb
z2.rb:4:in `not_before=': error getting time (OpenSSL::X509::CertificateError)
 from z2.rb:4:in `<main>'
ゲゲゲっ、not_beforeやnot_afterを設定することができません。設定した値が悪いのかといろいろトライしてみるも全て失敗。ウンウン、オイラはRuby+OpenSSL素人だから自分の書いたコードが悪いんだろうと思ったわけです。

で、バンドルされている単体テストのコードなら動くだろうと"test_x509cert.rb"を動かしてみるも

%ruby test_x509cert.rb
Loaded suite test_x509cert
Started
EEEEE
Finished in 0.046875 seconds.
 1) Error:
test_extension(OpenSSL::TestX509Certificate):
OpenSSL::X509::CertificateError: error getting time
  utils.rb:87:in `not_before='
  utils.rb:87:in `issue_cert'
  test_x509cert.rb:25:in `issue_cert'
  test_x509cert.rb:93:in `test_extension'
:以下略 (5つのテストケース全滅(泣)
単体テストだってnot_before、not_afterは設定できないじゃ〜〜ん。自分の環境設定が悪いんだろうといろいろ調べてもみましたが、悪いところはなさそう。OpenSSLのDLLのバージョンがいけないのかと、上のガイド通りだと0.9.8dが入るところを0.9.8l(最新)にしてもやはり同じ。単体テストが通ってないようなバイナリが配られてるなんてヒドイ、、、と愚痴りたくもなります(涙)。

試しにPKCS#12を読んでみるに、、、

証明書を作るのはとりあえずあきらめPKCS#12の中に入った秘密鍵で署名なんかしてみようかと、PKCS#12を読み込んでみるに、、、

require 'openssl'
p12 = OpenSSL::PKCS12.new(File.read("test.p12"), "password")
これを実行すると
% ruby p12_1.rb
p12_1.rb:4:in `initialize': PKCS12_parse: mac verify failure (OpenSSL::PKCS12::PKCS12Error)
 from p12_1.rb:4:in `new'
 from p12_1.rb:4:in `<main>'
パスワードが間違っている時に出がちなエラーとなります。これも、いろいろ手を変えやってみましたがうまくいきません。

で、詳しい方に聞いてみるに、、、

どうやらWindows版のRuby 1.9系のOpenSSLモジュールはちゃんと動かないと聞きました。 ちょっと試しただけで2つのメソッドが期待した動作をしないわけで、正しく動くのもあるんですが、ちょっとおっかなくて使えないですね。う〜〜む残念。なんか、やる気が失せちゃったなぁ、、、、UbuntuでもRubyとOpenSSLを入れてみたら、前述のコードは何の問題もなくスルっと動きました。

% aptititude install ruby1.9
% aptititude install libopenssl-ruby1.9
エラー情報を元にGoogleで検索してみたりしたんですが、殆ど何もヒットしませんでした。みんな、同じ問題に出くわしてないのかなぁ、、、Windows版のRuby 1.9でOpenSSLを使う場合には気をつけましょうってことで、、、

PythonのGoogle Calendar Data APIを使ってみた

自分のオフィスでは、社員共通のスケジュール管理はサイボウズOffice6を使っています。利用者のコメントなんか見ていると他の製品やサービスとの連携は難が多いようです。

最近、iPhoneを手に入れまして、スケジュール管理は「さいすけ」が評判がいいようなので、基本的には無料アプリばっかりで通していたんですが、これだけは買ってしまいました。
さいすけ

さいすけはGoogleカレンダーと同期ができて、iPhoneでちまちまスケジュール入力するよりも、パソコンでGoogleカレンダーに入力する方が大量にスケジュール入力するときは楽です。

さて、これらのスケジュールの同期を取る場合、

  • サイボウズはスケジュールをCSVテキスト形式でインポート、エクスポートできる。

  • GoogleカレンダーはRFCにもなっているiCalendar形式でインポート、エクスポートできる。

  • さいすけはGoogleカレンダーとボタン一つで同期できる。


ということで何とか同期はできそうです。

ツールとしてはogawaさんのcybozu2icalというオープンソースがあるんですが、自分のcygwin環境ではうまくインストールすることができませんでした。

仕方なく、とりあえず以下の3つのスクリプトを作りました。

サイボウズのスケジュールのCSVエクスポート
サイボウズのスケジュールのエクスポートをブラウザからでなくコマンドラインから行えるようにしたスクリプト。開始月と期間の指定ができる。
csvの差分ファイル作成ツール
サイボウズのスケジュールをCSVでエクスポートした際、同じ期間で古いのと新しいのとを比較して、追加になったイベントのCSV、削除になったイベントのCSVを生成するスクリプト
サイボウズのCSVからGoogleのiCalendarに変換する
サイボウズのCSV形式のファイルからGoogleカレンダーでインポートできるiCalendar形式に変換するツール

両方ともPerlのText::CSV_XSモジュールを使った簡単なものです。

これで、サイボウズに新規に登録されたものだけを、Googleカレンダーにインポートして登録するところまではでき、さいすけとも同期が取れました。

でも、サイボウズでキャンセルになったスケジュールをGoogleカレンダーで削除するところは標準機能だけではダメなようです。

仕方なく調べてみると、Google Calendar Data APIというのがあって、カレンダーなんかも操作でき、Java、.NET、Python、PHP、Objective-C、JavaScriptなど様々な言語をサポートしていることがわかりました。

自分としてはキャンセルされたスケジュールの削除だけが、とりあえずできればよいので、簡単そうなPythonを使ってみることにしました。

ここからgdata-2.0.5.zipというPythonのライブラリを落とします。

Python 2.2以上に対応しているそうで、cygwinでは2.5.2だったので問題ありませんでした。インストールは以下で終わりです。

% unzip gdata-2.0.5.zip
% cd gdata-2.0.5
% ./setup.py install


さて、簡単なところからGoogleカレンダーの登録されているイベントを表示するようなサンプルを動かしてみようと、一覧表示部分を抜き出して実行しましたがダメでした。

#!/usr/bin/python
import gdata.calendar.service
client = gdata.calendar.service.CalendarService()
client.email = 'あなたのアドレス@gmail.com'
client.password = 'パスワード'
client.source = 'Google-Calendar_Python_Sample-1.0'
client.ProgrammaticLogin()
feed = client.GetOwnCalendarsFeed()
for i, an_event in enumerate(feed.entry):
 print '\t%s. %s' % (i, an_event.title.text,)
 for p, a_participant in enumerate(an_event.who):
  print '\t\t%s. %s' % (p, a_participant.email,)
  print '\t\t\t%s' % (a_participant.name,)
  print '\t\t\t%s' % (a_participant.attendee_status.value,)


AttributeError: 'CalendarListEntry' object has no attribute 'who'


動かないサンプルなんか入れとくな〜〜〜っ!!!と怒りの気持ちをおさえつつ、queryなら動くようなのでちょっと手直しして

#!/usr/bin/python
# coding: cp932
import gdata.calendar.service
client = gdata.calendar.service.CalendarService()
client.email = 'あなたのGmailアドレス'
client.password = 'パスワード'
client.source = 'Google-Calendar_Python_Sample-1.0'
client.ProgrammaticLogin()

query = gdata.calendar.service.CalendarEventQuery('あなたのGmailアドレス', 'private', 'full')
query.max_results = 50

feed = client.CalendarQuery(query)
for i, an_event in enumerate(feed.entry):
 title_u8 = an_event.title.text
 title = unicode(title_u8, 'utf-8').encode('cp932', 'replace')
 when = an_event.when
 print '件名: %s' % (title,)
 print '場所: %s' % (an_event.where[0].value_string,)
 print '詳細: %s' % (an_event.content.text,)
 print '日付: %s - %s' % (when[0].start_time, when[0].end_time,)
 print '参照: %s' % (an_event.GetEditLink().href,)
 print ''


実行してみるとカレンダーに登録されたイベントが表示されます。

件名: 仕事始め
場所: None
詳細: None
日付: 2010-01-04 - 2010-01-05
参照: http://www.google.com/calendar/feeds/○×1

件名: PKI定点観測
場所: None
詳細: None
日付: 2010-01-18 - 2010-01-19
参照: http://www.google.com/calendar/feeds/○×1


さて本題のカレンダーのイベントの削除ですが、消したいと思うイベントをクエリや件名などで絞り込んでから、実際に消すにはイベントan_eventに対して以下を実行すればオーケーです。

client.DeleteEvent(an_event.GetEditLink().href)


サイボウズからエクスポートされたCSVに対して、差分生成ツールによりスケジュールの更新によりキャンセルされたイベントのCSVは出てくるので適当に処理して、上のDeleteEventメソッドを実行してやればよいわけです。

APIを勉強した今では、登録も削除もAPI使った方が一貫性があるような気もしますが、とりあえず目的は達成されたので、時間が取れるまではこれで凌ごうと思っています。

ではでは、













最新記事
Categories
Archives
Twitter
記事Google検索

本ブログ内をGoogle検索
Yahoo!アクセス解析
Travel Advisor
記事検索
QRコード
QRコード
  • ライブドアブログ