（いまさらSHA-2対応）署名のハッシュアルゴリズムSHA-256化で困らないように

証明書の期間が長くて、未だ対応できていないサーバーも散見されるので、備忘録。
ちなみに（SHA-2はSHA-256、SHA-512などの総称）

実際のSSL通信暗号強度の問題ではなく、署名の信頼性の問題。[参考](http://itpro.nikkeibp.co.jp/article/COLUMN/20071012/284426/)

#SHA-1廃止
ハッシュは認証局にCSRを渡すとき、認証局から証明書を受け取るときに改ざんされていないことを確認するために必要。
コンピューターの性能向上によって、従来のハッシュアルゴリズム（MD5やSHA-1）では十分なセキュリティが確保できなくなってきているため、既にWebブラウザなどのSSLを使用するクライアントではSHA-1が廃止されている。
[（Symantec社）ハッシュアルゴリズムのSHA-1からSHA-2への移行に関して](https://www.symantec.com/ja/jp/page.jsp?id=ssl-sha2-transition)

# SHA-2対応を確認
SSLやアプリケーション発行者の署名（コードサイニング）に使用している証明書をSHA-2署名にする必要がある。そのために、証明書を利用するサーバーおよびクライアントがSHA-2に対応していなければならない。
対応バージョン出ない場合は、適宜アップデートする。

##サーバー
SSLを利用するOS、ミドルウェア、キー生成ツール等がSHA-2ハッシュアルゴリズムに対応しているか確認する。


| 対象 | 対応バージョン |
|:--|:--|
|Windows Server| 2003 + SP2 + MS13-095|
|.NET Framework(Mscorlib.dll:System.Security.Cryptography)|1.1以降|
|Mac OS X | 10.5以降 |
|Java(rt.jarjava.security.MessageDigest) |1.7.0 以降、1.6.0_17 以降、1.5.0_22 以降、1.4.2_19 以降|
|openssl|0.9.8o以降、1.0.0以降|

##クライアント
|対象|対応バージョン|
|:--|:--|
|Windows|XP+SP3、Vista以降|
|Mac OS X|10.5以降|
|GoogleChrome|39以降でSHA-1警告、48以降でSHA-1エラー|
|Mozilla Fire Fox|43以降でSHA-1エラー |

#署名アルゴリズムSHA-2を指定してCSRを発行する

## OpenSSL
openssl reqで`-sha256`パラメータを指定する。

例：2048bitのRSAキーを発行してDES3で暗号化した（パスワード要求される）キーを発行する。（秘密鍵なので、/etc/ssl配下など管理者のみアクセスできる場所へ厳重保管）

```
# openssl genrsa -des -out private.key 2048
```

SHA-256で署名リクエストを作成

```
# openssl req -new -sha256 -key private.key -out server.csr

プロンプトにしたがって組織情報を入力
```

`server.csr`をCAに提出して署名してもらう。

※自己署名する場合
自己認証局の秘密鍵（ca-private.key）を使用して、server.csrからSHA256ハッシュで署名し、365日のserver.crtを作成する。

```
# openssl req -x509 -key ca-private.key -in server.csr -out server.crt -days 356 -sha256
```

## java keytool
-certreqで`-sigalg SHA256withRSA`パラメータを指定する。

例：2048bitのRSAキーを発行し、別名sslserverとしてキーストアserver.jksへ保存。（秘密鍵を含むので、管理者のみアクセスできる場所へ厳重保管）

```
# keytool -genkeypair -keyalg RSA -keysize 2048 -keystore server.jks -alias sslserver
```
キーストアの中にある、別名sslserverのエントリー（さっき生成した鍵）を元に署名アルゴリズム(SHA256withRSA)を指定して署名リクエストserver.csrを作成。

```
# keytool -certreq -alias sslserver -sigalg SHA256withRSA -file server.csr -keystore server.jks 
```

`server.csr`をCAに提出して署名してもらう。

## Windowsのcertreqコマンド
手元では検証していないので、[このへん](https://technet.microsoft.com/fr-fr/library/ff625722%28v=ws.10%29.aspx#BKMK_CreateInf)を参考に...
Server2003 XPは[管理ツールパック] (http://go.microsoft.com/fwlink/?LinkID=8136)が必要。

```text:server.inf
[NewRequest]
Subject="cn=[Subject]"
EncipherOnly = FALSE ;WindowsXP or server2003の時のみ必要
Exportable = FALSE   ;秘密鍵のエクスポートをしない
KeyLength = 2048　　　　;キーサイズ 2048 bits
KeySpec = 1
KeyUsage = 0xA0
MachineKeySet = TRUE
RequestType = PKCS12

; Vista、Server2008以降は必要？
[Extensions]
2.5.29.17 = "{text}"
_continue_ = "dns=[dns server]&"
_continue_ = "dn=[domain name]&"
_continue_ = "url=[url]&"
_continue_ = "ipaddress=[IP]&"
_continue_ = "email=[mail]&"
_continue_ = "upn=[upn]&"
_continue_ = "guid=[guid]&"

; XP, Server2003以前は必要？
SAN="dns=[DNS]&ipaddress=[IP]"
```

```
C:\>certreq.exe -new -f server.inf server.csr
```


`server.csr`をCAに提出して署名してもらう。

#証明書の確認

##OpenSSL
```
# openssl x509 -in server.crt -text | grep sha256
```

##java keytool
```
# keytool -printcert -v -file test.crt | grep SHA256
```

##windows
そのまま証明書ファイルを開く。

#証明書インポート
sha1と同じ手順。
**※中間証明書などが変更になっている可能性があるため、中間と合わせて（Chain）で更新する。**

##open ssl
pkcs12キーストアへインポート

```
# openssl pkcs12 -inkey private.key -in server.crt -export -out server.pkcs12 -certfile intermediate.crt
```

##java keytool

中間と結合してからインポート

```
# cat intermediate.srt server.crt > chained.crt
# keytool -importcert -keystore server.jks -file chained.crt -alias sslserver
```

#参考
[（Symantec/旧verisign）ハッシュアルゴリズムのSHA-1からSHA-2への移行に関して](https://www.symantec.com/ja/jp/page.jsp?id=ssl-sha2-transition)
[（Global Sign）SHA-1からSHA-2への移行について](https://jp.globalsign.com/sha256/)
[（cybertrust）SSL SHA-1 証明書の受付終了と SHA-2 証明書への移行について](https://www.cybertrust.ne.jp/sureserver/productinfo/sha1ms.html)
[図解で学ぶネットワークの基礎：SSL編](http://itpro.nikkeibp.co.jp/article/COLUMN/20071012/284426/)
[technet](https://technet.microsoft.com/fr-fr/library/ff625722%28v=ws.10%29.aspx#BKMK_CreateInf)