投稿

ラベル(Java)が付いた投稿を表示しています

AES-GCM 暗号が作れた

AESとGCMどちらも実装をしてみていたが、GCMの仕様が読みにくかったので進んでいなかった。 AESは前回からあまり変わらず適度に速いので、GCMの速度をどれくらいまで上げられるか、の前にGCMを実装できるのか? というところから。 GCMはほぼCTR Mode とハッシュ計算で認証コードの計算をするだけの組み合わせなので、CTRを若干修正したものとIVなどの初期化ができればやや完成、となる。 やや難解な初期化 CTRモード 認証タグの計算いろいろ AADの計算 ガロアさんの計算をビット反転で テストパターンをみつけてやる気を出して、なんとか完了。速度的には低下なし。本体のCTRっぽい計算のあと、認証タグの計算を別スレッドに分けてみた。2スレッドに分けることでAES-NIは使ってないのに1.5Gbpsくらいは出ていてJava標準のより速い。という結果が出てしまった。 GCM は CTRの拡張っぽい構造でストリーム暗号。本体の GCTR? とハッシュ値計算のGHASH に分けて作ったりすると楽か。スレッド分けは、本体データをハッシュ計算用にメモリに蓄積しながら本文の暗号を行う。ハッシュ計算用のスレッドが終わっていれば再始動する、くらいのものでうまく動く。スレッド間に挟むのはいつもの自作Packetなので読み書き別々にしても全読みしなければ多分問題なさそう。 基本的な高速化手法はAESもGCMも内部をlong型で64bit x 2 にすること。8bit x 16でやるよりXORが全然はやい。 GCTRとCTRの違いはIVのカウンタ部分が32bit固定になることぐらいでいいのかも。 IVの初期化は96bit 入力を使う、それ以外はGHASH で混ぜる、だがTLSでは96bit限定かもしれない。96bitの場合カウンタは乱数が入らないところからはじまる。計算された値はJ0っぽい値になる。 IVは最初の値をGHASH用に、次からGCTR用に使うのでCTRの初期値もひとつかふたつずれる。  GHASHの入力は内部で持つHから計算する、 ハッシュ計算用にAAD とかいう感じの暗号化しないヘッダ的なものを追加可能で本体は暗号化後の値で計算する。GHASHは2つを載せる前提の構造になっている。Paddingは単純な128bitまで0詰め。最後にAADと本体Cの2つのビット長...

AES高速化をもう少し

割と最速だったJavaで作ったAES実装もJDKのAESがOpenSSLかなにかのハードウェア実装を使うようになったおかげで数倍の差がついてしまった。KCyper-2がまだよくわからないのでAESをつついてみたりPKIの方を見たり。 Intel CPU にはAES NI というAESの計算補助的なものがあり、AMD Ryzen 2600X でも使えるようになっていて速くなる。OpenSSLが対応しているのでJavaでもOpenSSL経由でいつのまにか使えるようになっていて、高速処理ができている。 AES NIもたぶん途中の計算をまとめられるだけまとめてあらかじめ計算しておき配列に押し込んで高速化をする手法。 ソフト的にも高速化していくと同じような実装になって普通に解説されているような実装の数十倍はやくなる。 特に競ってみようというわけではないが、いろいろなハッシュや暗号を実装してみるなかでAESも乗せてみたついでに高速化もしてみたというのが前回くらい。32bitまとめるところで高速化ができたが、64bitにしてみたらもう少し速くなった気がするのでそのあたりで止めておいた。 decode側は最適化をどうやればいいのかと思っていたら、計算順を変えることでencodeと同じように最適化できることもわかったので割と高速な方にすることはできた。encodeと同じように64bit化したらencode以上に速くなった。  AES-CBC Ryzen 7 5800X で 初期値 1400Mbps、JavaのJITが効いてくると1650Mbpsくらいまで速くなる印象。AES-NIだと初期値2500Mbpsくらいなのでかなり追いついている。AES単体だとまだまだ差は大きいが今は未計測。 元になるAESのコードが跡形もなくなってきているので、原型を留めたコードを別に残しておかないと何の参考にもならないなと。 速度比較、AES単体ではなく若干実用的なAES-CBCで比較してみることにして、JDKのコードと2倍くらいの差まで迫ることができる。ということはJDKのCBCが遅いのか。CBCで64bit演算してそのままAESに持っていくことで高速化できている感じ。JDKはそのあたりが遅い印象。 最近の主流はCBCからGCMかなんかになってきているようなので、そっちも実装したいが仕様だけ見て...

RSA鍵を作る

最近暗号系をいろいろ実装してみている中で PKCS #1 の RSA も必要になってきたので実装してみた。中身がわからないと使いにくいタイプ。 RSA は公開鍵暗号という形で秘密鍵、公開鍵の2つの鍵を使う。AESなどの共通鍵暗号とは違うところ。 公開鍵で暗号化、秘密鍵で復号ができるのがひとつめ。 秘密鍵で署名。公開鍵で検証。これが2つめ。  公開鍵暗号共通の特徴ではなくRSAの特徴のようなので注意。 アルゴリズム的にはガロア体と同じようなものを作って2つの状態を行き来してる感じがした。 何に使えるのか。ひととおりバイト列の暗号化などにも使えるが、速さが出ないので署名用途の方が主流で暗号化も一部用途に限定して使う場合が多い。 秘密鍵と公開鍵の中身を見ていく。 RSAは大きい数の因数分解が難しいというところから作られているので2つの素数から鍵を作る。 素数(prime)2つ(pとq)を決める。2048ビットのRSAだと1024ビットくらいの素数を2つ。今なら3072ビットくらいが最低ラインになってきているので1536ビットくらいの素数を2つ。 Java で作るのでいろいろ省略できるところは省略する。 乱数はjava.math.SecureRandom っぽいところから。安全かどうかは不明。他の要素があればいろいろ混ぜるとより安全かも。普通のRandomは安全ではない。 SecureRandom srnd = SecureRandom.getInstanceStorong(); BigInteger p = BigInteger.probablePrime( len / 2, srnd ); BigInteger q = BigInteger.probablePrime( len / 2, srnd ); これで素数2つを作ってくれるのでおまかせ。素数ではない場合もあるらしい。 modulus 素数2つを掛けたもの 変数名は n など。 BigInteger n = p.multiply(q); // n = p * q nをpとqに素因数分解するのが難しい。 次はeとdという指数(exponent)を決めていく。 eは公開指数(public exponent)、dは秘密指数(private exponent)。 e * d = 1 mod (p - 1)(q -...

GitHubのMavenあれなのでMaven Centralを使うことにした

GitHubのMaven Repositoryがあれなので、Maven Central Repositoryに登録することにしてみた。 詳細は省略してざっくりした手順。 sonatype というところが管理しているらしい sonatype OSS Repository Hosting (ossrh)というのが本当の名前か。 手順はこんな感じで案内されている。 https://central.sonatype.org/publish/publish-guide/ アカウントは以前から作ってあったので、その先から。 プロジェクトを登録する。groupId毎に申請する必要があるので別プロジェクト、サブグループなどにする場合は再度申請するらしい。SoftLib系はgroupId 1つでいいかと思うのでまだ1つしか登録はしていない。 申請はフォームがあるのでそこから申請する。 内容はURLなどと、プロジェクトの説明。 掲示板っぽくやりとりするが、機械的に処理されるので特に詳しく書く必要はない。他の人が申請しているのを見て真似してもいい。 groupId は独自ドメインの他、GitHub系も使えるが今回はドメインを持っているので使う。 GitHubのプロジェクトや独自ドメインの所有証明(DNSにTXTレコードを追加など)ができると、プロジェクトの登録は完了。 GPG(PGPのGnu版っぽいもの)の署名が必要なので、鍵と公開鍵を作ってどこかに登録する。Thunderbirdなどで使っているのあがあれば使えるのかもしれないが別で作った。GitHubにも登録しておけるかも。 事前に準備しておくのはMavenなJavaプロジェクト。 ソースコードはjavadoc までエラーなく生成できる状態になっているといい。 Mavenのpom.xml と settings.xml にossrhとGPGの鍵などを登録、ライセンスなど必要な項目も追加してdeployすると公開できる。コードのjarの他、ソースコード、javadocと各GPG署名が公開される。 gitにもGPG鍵は登録できるらしいがNetBeans IDEから更新しているので動作しているのかは不明。 リリース版は、整合性の調査など時間がかかるが数分程度で公開される。同じバージョンは1度しか公開できないし、削除もできないはず。 SNAPS...

GitHub に Mavenリポジトリ公開してみたら失敗した

 GitHub PackagesでMavenリポジトリ?がつかえるようになっていたということで挑戦していたが、しばらくいろいろと不明でつかえなかった。 今回 GitHub Actions は使わない。非公式の方法も使わない。 https://docs.github.com/ja/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry 日本語の説明はあるが、例がてきとーすぎて不明点が多い。 いろいろわからない部分が明確になったので、ざっくりなんとかしていくかもしれない。 完全な公開ではなく、管理にもダウンロードにもTOKENが必要なので使い道は特定のもののみで微妙。 OWNER/REPOSITORY これは、https://github.com/okomeki/SoftLibREST の場合は OWNER が okomeki REPOSITORY が softlibrest となる。 大文字がつかえないのがまず引っかかっていたのと、REPOSITORY に何を指定していいのかわからないのでエラーの意味から何も読み取れず引っかかっていた。 OWNER は GitHub のアカウントまたは組織単位の場合は組織名(Organization)で指定する。大文字は使えないので小文字にする。 REPOSITORY は 何でも指定していいわけではなく、GitHubで使っている Repository名、かつ大文字は小文字に変えるという制約がある。サンプルが test なのでいろいろ不明だったり。 Maven では pom.xml に公開先 repository を指定する。pom.xml の artifactId とはあわせておきたいが、あわせなくてもいいかもしれない。 groupId, artifactId も仮で大文字など使っていたら小文字とハイフンぐらいに変更する。artifactId が大文字制限に引っかかっているようなので SoftLibABNF から softlib-abnf に変更してみた。 アカウントが okomeki, Repository名が SoftLibABNF、pom.xml の groupId を net.siisise、 ...

Java API for JSON Processing,JSONBと比較してみた

ABNFパーサを作ったおまけでてきとーにRFCだけ見てなんとなく作ったJSON実装(SoftLibJSON)がどれくらいJava標準(Java API for JSON Processing と JSONB)に近いのかなと思い、比較してみた。 結果、一応元のRFCがあるのでほぼそっくりではあるのだけど、微妙に違うのでそのあたりの解説と、今後どうするのかとか。   Java API for JSON Processing SoftLibJSON   TEXTぱーす   どこか JSON.parse()                   JSON TEXT化   JSONValue.toString()    Object→JSON   JSONValue.valueOf()    JSON→Object   JSONValue.map()    値 JsonValue JSONValue         NULL JsonValue.NULL JSONNULL    true JsonValue.TRUE JSONBoolean    false JsonValue.FALSE JSONBoolean    数値 JsonNumber JSONNumber    配列 JsonArray JSONArray    構造体 JsonObject JSONObject   こうしてみると、JsonValue からの継承関係はだいたいおなじ。JsonArrayはList,JsonObjectはMapを継承するのに対して、SoftLibJSONではJSON Pointerに対応するための機能も埋め込んだため、JSONArrayとJSONObjectではJSONCollectionとしてまとめたものを継承しているのが違い。 値の取り出し方はJava APIの方が型変換の呪縛でいろいろ...

RazpberryPi Zero WでJavaを使おう

というわけでRaspberryPiどころか家でPCにも触ってなかったのですが最近Ryzen 5 2600XなPCを組んでからプログラミングやらいろいろ再開中で、RaspberryPiでWebサーバでもと思ったら2Bが行方不明なのでZero Wを買って挑戦してみることに。 いろいろ罠にはまります。 RaspberryPi Zero WとWHをスイッチサイエンスで1つずつ購入 microSDXCカード 128GBを2枚購入していた(危険 class 10、UHS-Ⅰ Speed Class 1、A1対応) microSDHC 8~32GBが推奨 USBキーボードがなかった(Logiのワイヤレスドングルので可。SANWAのキーボードもあった) てきとーなmicroUSBで繋がる電源 PuTTYとWinSCPでリモート接続 本体の選択 まずは本体の選択、初心者はできれば3B+かな。Zeroは2台目以降でもいいのかもしれない。 フルサイズUSB端子がある、有線LANがある、無線LANもある、HDMIがフルサイズ、などの理由です。変換ケーブル類も高いので予備がないなら3B+です。 Zero Wは、シングルコアARMv6、microUSB OTGがある、有線LANがない、無線LANがある、HDMIがminiサイズ、といろいろと不便です。Zeroになると無線LANまでないので別途用意しないといけません。 Javaを動かしたいならARMv7以降のCPUのものを選ぼう。NOOBSにはARMv7対応のJava11くらいが入っていた。Zero WはARMv6です。あとで対応したJavaを探します。 メモリーカード、OSの選択 メモリーカードの設定から入ります。microSDHC、microSDXCが使えますが、推奨は8GB以上のようです。microSDXCはフォーマットがFAT32ではないという理由で初心者にはおすすめしません。というわけで、初心者向けの容量は8GBから32GBの間で選びます。挑戦したい人はmicroSDXCも今は512GBくらいまであるので選び放題です。 速度など容量以外の選択基準では、class10、UHS不要、A1かA2対応のスマホ用に最適化されているようなものや、書き換えに高耐久なもの、がおすすめです。PCで最初に書き込むのが速...

Raspberry Pi 2でTomcat

Raspberry PiにはRSコンポーネンツ版とElement14版があると。 違いは箱と説明書ぐらいかな。 PCとの比較 マザーボード+CPU+GPU+メモリ → Raspberry Pi 電源 → USB ACアダプタ HDD/SSD → microSDHCカード ケース → ケース Pidoraも試してみようと思ったのですが、まだRaspberry Pi 2には対応していないようですね。LinuxはSnappy Ubuntu CoreかRaspbian Debian Wheezyですか。 Raspberry Pi 2のRaspbianにJDK8を後で入れてみましたが、Raspbian February 2015には標準で入っているようです。 Tomcatはopenjdk7を探しているようなので、OpenJDK7やOracle Java SE 7を追加で入れる場合は apt-get install openjdk-7-jdk または apt-get install oracle-java7-jdk apt-get install tomcat7 くらいでいいようです。openjdk-7-jdkとtomcat7で使ってみることにします。 CATALINA_HOMEは /usr/share/tomcat7 CATALINA_BASEは /var/lib/tomcat7 さらに conf  → /etc/tomcat7 logs → /var/log/tomcat7 work → /var/cache/tomcat7 なのでしょうか /var/lib/tomcat7/webappsは使いたくないのでserver.xml を適度に編集します。 Apacheは2.2系が入っているのか入れられるのかなので、mod_proxyとmod_proxy_ajpを有効にしてTomcatと繋ぎます。mod_jk2よりはるかに簡単ですが、ApacheもDebian系の癖がある分難解でしたがとりあえず略で。 /etc/apache2/mods-enabled にmods-availableのmod_proxy系のシンボリックリンクを貼って、sites-availableとsites-enabledも同様にしま...

Raspberry Pi 2 Model Bとやらを買ってみたり

教育用途で開発された小型で安いボード型のコンピュータ、イギリス発のRaspberry Piとやらが人気のようで、最近Raspberry Pi 2がリリースされたのだとか。 なにができるのか 基本仕様はクアッドコアのARMプロセッサにメモリ1GB、microSDHCなストレージにUSB2.1とHDMI、Ethernet、I/O用のGPIOやカメラ用の端子などがついている。 それでサイズはカードサイズ、価格は4200円から5500円程度。電源もケースも付いていないのでセット購入か別途用意すると8千円程度で全部そろうか。あとはストレージ用のmicroSDHCカードの32GBぐらいとUSBのマウスとキーボードも必要になるので余りものなどを探しておいたり。 で、基本的には専用の各種Linuxディストリビューションの簡易イメージなどが用意されていて、GPIOというのを使ってハードウェアを触ってみたりということができたりするそうな。X Window的なものやJavaなども使えます。 似たようなものにはChromecastとかFirefox OSやAndroidのHDMI接続できるちっちゃいのがありますが、これはOSから好き放題にできます。 購入とか RSというところで製造しているのかな? KSYというところでケースとのセットがあったのでそっちで購入してみた。一部削れば2でも使えるみたいだけど、2対応のケースはまだまだ少ないのかな。 Windows 10が無償配布されるらしいという話もありますが、今回は一般的なLinuxを入れることにしますよ。サーバ類はパソコンが入手しやすく安かった時代も今は昔かな。 最初に購入したのはRaspberry Pi 2 Model Bとケースだけで、あとは余りものなどを流用してみたのでお安くできました。 (サーバ用に)必要なもの Raspberry Pi 2 Model B セットで買ったケース (なくてもいい) microUSB電源(1A~2A) Ankerの5ポートUSB電源に仮接続 microSDHC 16GB~32GB程度 Class 10推奨かな 余ってた32GB Class10を使う Ethernetケーブル 100BASE-Tくらいで使えるもの 設定などで一時的に必要なもの USBマウス...

Android Studio をダウンロード、0.1.2にしてみる

Google I/Oで発表されたAndroid Studioもv0.1.2とかになったのかな。 Windows 7(x64)環境で設定してみることにしましょう。 Android Studio v0.1.x http://developer.android.com/intl/ja/sdk/installing/studio.html v0.1.1がダウンロード可能です。 Java 2 SDK 1.7.0_21 (x64版) Androidの開発環境はJavaなので入れてない人はJDKを入れましょう。 JDK、Android Studioの順でインストールし、環境変数にJAVA_HOMEの設定も必要なのかな。 コンピュータを開き、システムのプロパティから「システムの詳細設定」を開くと「詳細設定」タブの中に「環境変数(N)」があるのでそれを開きます。(Windows 7) システム環境変数の方に新規または編集で変数名に JAVA_HOME変数値に Java 2 SDKのパス(x64版)を指定します。 C:\Program Files\Java\jdk1.7.0_21 ぐらいになるでしょうか。 Android Studioを起動したときに MSVCR100.dll がないといわれた場合にはVisual C++の再頒布可能パッケージが必要なようです。 Microsoft Visual C++ 2010 再頒布可能パッケージ (x64) http://www.microsoft.com/ja-jp/download/details.aspx?id=14632 または(x86) http://www.microsoft.com/ja-jp/download/details.aspx?id=5555 Welcome to Android Studio という小さめのメニューが開くととりあえず安心。 メニューは全体的に英語ですね。 下にCheck for updates now. などと表示されていればそこを、なくても ConfigureからSettingsを開き、UpdatesからCheck Now などを選ぶと 0.1.2がダウンロードできます。

Java SE 7 がリリース

数年ぶりにJava SE が7になってリリースされた。 このバージョンのリファレンス実装はOpenJDKがベースになっているようだ。 ドキュメント類は英語のみではあるが、日本語や中国語版が期待できそうだ。