- PR -

javaとC++でハイブリッド暗号の実装について

投稿者投稿内容
るな
常連さん
会議室デビュー日: 2006/03/09
投稿数: 21
投稿日時: 2006-06-09 20:29
お世話になっております。

サーバ側はC++(VC++)で実装されたサービスが起動しており
クライアント側はjavaでソケットを使ったデータのやり取りを行っております。
現状、暗号化が行われていません。
そこで
http://c4t.jp/introduction/cryptography/cryptography05.html
上記URLの図にあるような暗号方式を行ったデータのやり取りを行いたいのですが
実際にどのようなAPI等を使って実装したら良いのかまでは辿り着けませんでした。
手順は理解しているつもりです...
1.サーバ側で公開鍵、秘密鍵を作成し公開鍵をクライアントへ送信。
2.クライアント側で共通鍵作成し公開鍵を受け取り、
  その公開鍵で共通鍵を暗号化しサーバへ送信。
4.サーバ側で受け取った共通鍵を秘密鍵で復号。
3.以後のデータのやり取りは共通鍵を使って暗号化&復号を行う。

【環境及び要望】
・WinXP
・C++(VS6.0)
・java(j2sdk1.4.2_9)
・RSAの様なライセンス問題が発生しない出来るだけ標準のもので実装したい
※クライアントはC++版もあるのですがjava版で実現出来れば特に問題なく実現出来ると考えております。

javaのみの内容ではないのですが何卒ご教授の程宜しくお願いします。
未記入
会議室デビュー日: 2006/06/12
投稿数: 1
投稿日時: 2006-06-12 12:24
Java client で PGP 等の暗号を利用するのであれば
JNI (Java Native Interface) を使用して C の native を動かしてみては如何でしょうか。

http://www2s.biglobe.ne.jp/~katsum/java/samples/Jni/jni.html

が参考になると思います。

himikuni
スフレ
ぬし
会議室デビュー日: 2005/05/27
投稿数: 281
お住まい・勤務地: 東京
投稿日時: 2006-06-12 12:44
一番簡単なのは、SSLを導入することだと思いますが。

それはサテオキ、Javaでは、共通鍵の生成は javax.crypto.KeyGenerator、鍵を公開鍵で暗号化するのは javax.crypto.Cipher で init(WRAP_MODE, ...) してから wrap()、共通鍵での復号は javax.crypto.Cipher で init(DECRYPT_MODE, key) してから update() & doFinal() です。

Windows 側は経験がないので具体的なことは知りませんが、Crypto API を使うのでしょう。
るな
常連さん
会議室デビュー日: 2006/03/09
投稿数: 21
投稿日時: 2006-06-12 19:59
お世話になります。
回答有難うございます。

早速、検討及び試行してみます。

また分からない事がありましたら質問させて下さい。
るな
常連さん
会議室デビュー日: 2006/03/09
投稿数: 21
投稿日時: 2006-06-13 18:46
お世話になります。

早速JNIを検討した所、ハード面の都合から
「java側はピュアjavaで!」と言うお達しがありました...
ほぼ振り出しに戻ったと言った感じです。

スフレさんの言うjavaでの共通鍵の生成&符号化は分かるのですが
実際にその符号化された鍵使ってC++で暗号化&復号する方法がありますでしょうか?
未だ調査中ですがC++側でペアキー生成し、java側でそれを使って
暗号化する方法も解決しておりません。
サンプルコード等ありますと助かります。
加納正和
ぬし
会議室デビュー日: 2004/01/28
投稿数: 332
お住まい・勤務地: 首都圏
投稿日時: 2006-06-14 00:34
引用:

「java側はピュアjavaで!」と言うお達しがありました...



え〜、SSLという手段は検討したのでしょうか。
今現状、自分で「暗号化」という手段を「セキュリティ的に」設計するのは
無理があります。SSL 3.0は、まぁやってあります。

SSLはJavaは、JSSEで、ふつーにPure Javaです。
ちなみに、JNIもPure Javaなんですがね。

JNIはPure Javaじゃないなんてのは実装を知らない人の言い分です。
が、ぢっさい「Pure Java」==「OSを「要求で」定義しない」という
言い訳にしか使わないので、Sunとどっこいどっこいですが。

で、なんの話でしたか。「暗号化」なんて「無駄」という話ではなくて。
私はいつも書くのですが。セキュリテイ設計をしない「暗号化」なんて、
単に無駄な処理を間にはさむだけで「完全性」をそこなう「無駄」な行為だと。

大抵は「暗号化」は「機能向上案件」でよく使うんですよね。「暗号化」なんて必要ないのに。
次はSOA化かな?でその次はSOA化の「似非」セキュリティとやらなわけだ。
「無駄」がかさむだけなんだけどね。

その次が「嘘リッチクライアント」で、、、次は何?
「嘘」と「似非」ばっかり、、、あと追加で「法的対応」。

まぁ、ともかく。

C++側とやらで「暗号化」というキーワードでは、広すぎてなんなので
CryptoAPIはしらべたのでしょうか。

http://www.kumei.ne.jp/c_lang/sdk3/sdk_267.htm

これとか。

CryptEncrypt()関数とCryptDecrypt()関数が「暗号化」と「復号化」

http://nienie.com/~masapico/api_CryptAcquireContext.html

には、鍵生成(正確には鍵コンテナに鍵生成するのですが)のサンプルが載ってます。
鍵ペアでも、共通鍵でも(共通鍵は、鍵コンテナには入れないけれども)生成できます。

どんなんでも実装できますが、設計しない限りはなにやってるか分からない
状態になります。

ちなみにCryptoAPI単体でSSLサーバになる手段は、基本的にはありません。
もちろんSSLサーバの実装(例えばOpenSSL)を使えば別です。

CryptoAPIでSSLプロトコルを実装するなら全く別です。
そんな不思議な実装するならIIS使ったほうがましだ。。。

ん?!結局どのような設計をするかに戻るんだけど。。。

ちなみに.NET Framefork 2.0なら、SSLStreamを検討するんだけどね。。
使うかどうかはともかく。

要するに「設計」なのだが、、ぢつはだれも分かってない。。。
分かっても意味はない。。。
るな
常連さん
会議室デビュー日: 2006/03/09
投稿数: 21
投稿日時: 2006-06-15 20:08
お世話になります。
返信遅れましてすみません。
アドバイス有難うございます。

ピュアjavaの件は、どうやらクライアントは
PCだけではなくWinAPI等が使えないハードも視野に入れている様で...
その上でデータをベタに流すのは良くないだろうと言う事で
極力標準のもので行えないか検討している次第です。

CryptAPIもjavax.cryptoもおよそ使い方は分かるのですが
javaとC++とで互換のあるやり取りの方法が分かりませんでした。
もう少し調査したいと思います。
また、良い方法やサンプル等ありましたら宜しくお願いします。
加納正和
ぬし
会議室デビュー日: 2004/01/28
投稿数: 332
お住まい・勤務地: 首都圏
投稿日時: 2006-06-15 21:30
引用:

るなさんの書き込み (2006-06-15 20:08) より:

javaとC++とで互換のあるやり取りの方法が分かりませんでした。



WIN32API使えなきゃ、CryptoAPIなんか、さらに使えないのだが。。。
まぁいいや、それは。

どうなるんだっけ。一つ一つは面倒だなぁ。

(1)C++側
1.CryptAcquireContext(CRYPT_NEWKEYSET) CSP取得
2.CryptGenKey(AT_KEYEXCHANGE) 鍵生成
3.CryptExportKey(PUBLICKEYBLOB)鍵取得
(例: http://forums.belution.com/ja/vc/000/161/89.shtmlな感じ)

(2)Java
1.KeyGenerator keyGen = KeyGenerator.getInstance("DES"); 共通鍵生成
keyGen.init(56);
SecretKey key = keyGen.generateKey();
cipher.init(Cipher.ENCRYPT_MODE, key);
(例: http://www.techscore.com/tech/J2SE/JCE/5.html#jce5-2な感じ)
2.KeyFactory keyFactory = KeyFactory.getInstance("RSA");
3.RSAPublicKeySpec s2 = new RSAPublicKeySpec(new BigInteger(new BASE64Decoder().decodeBuffer(b2m)), new BigInteger(new BASE64Decoder().decodeBuffer(b2e)));
RSAPublicKey k2 = (RSAPublicKey) keyFactory.generatePublic(s2); 公開鍵をクラスに読む
(例: http://java-house.jp/ml/archive/j-h-b/047252.html)

(3)C++
1.CryptExportKey(PRIVATEKEYBLOB)秘密鍵取得
2.CryptDecrypt()?? 秘密鍵復号化
3.??? 共通鍵取得

あ〜、考えてみると
(1)C++->Java側の公開鍵フォーマット
(2)Java->C++の共通鍵フォーマット
が面倒かな。

一応、例で大体分かると思うけど。

スキルアップ/キャリアアップ(JOB@IT)