暗号化アルゴリズムの最初に、タイプ
1、キー
キー、通常は文字列または数値は、アルゴリズムが正しく平文を暗号化または暗号文を解読することができるように、暗号化または時間を解読するために暗号化や復号化アルゴリズムに渡されます。
2、暗号化アルゴリズムの分類
一般的には単方向および双方向の暗号化、暗号化と分類。
2.1、一方向の暗号化
それはユニークな暗号化された暗号化文字列を生成し、したがって、しばしば、データが送信中に変更されたかどうかを検出するために使用されるので、暗号化が暗号化されている非可逆な方法は、暗号化方式は、解読不能です。一般的な一方向の暗号化は、MD5、SHA、HMACがあります。私達はちょうどこれらの3つの簡単な暗号化が信頼できない、暗号化のための基礎としてそれらを使用しています。
2.2、双方向の暗号化
道の暗号化は、対称暗号化と非対称暗号化に分けることができます。秘密鍵復号アルゴリズムと処理:必要性は二つのことを持っているときに、暗号化と復号化の操作をします。
2.3、対称暗号化
対称暗号化キーとキーアルゴリズムの特性は、同じを使用して暗号化を解読するために使用されます。つまり、暗号化と復号に同じ鍵が使用されています。したがって、例のセキュリティを確保するための対称暗号化アルゴリズムは、セキュリティを行うことが重要な自然、のみ公開していない、人々は知って使用させることができます。
2.4非対称暗号化
非対称暗号化アルゴリズムでは、公開鍵が公開された公開鍵と秘密鍵の2種類があり、秘密を必要とせず、個人が保有する秘密鍵は、手入れの行き届いたと機密保持する必要があります。二つの異なるキーを使用して暗号化と復号化は、それはその名前の理由です。我々は、非対称暗号化アルゴリズムの一般的な、非常に幅広いアプリケーションであるRSA、話を聞いていると推定しています。
二、RSA
1、RSAがそれであることは何ですか?
RSAの暗号化アルゴリズムは、非対称暗号化アルゴリズムで、暗号化の一つは、復号化が別に必要使用して、アルゴリズムは、鍵のペアが必要であることを意味し、非対称と呼ばれます。これは、直接キーなしで送信することができ、復号化が完了しています。これは、直接転写キーによって引き起こさブレークのリスクを回避するために、情報のセキュリティを確保することができます。プロセスは、それぞれ、公開鍵と秘密鍵と呼ばれる暗号化と復号鍵のペアによって行われます。2間の数学的な相関関係があり、暗号化アルゴリズムの原理は、安全性を確保するために、整数の因数分解の大きな困難を行うことです。通常は個人を保存し、公開鍵は(同時にホールドよりもおそらくより)です。
2、原則
http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html
図3に示すように、RSA暗号化、署名差
暗号化と署名は、セキュリティ上の理由からですが、わずかに異なります。人々はしばしば暗号化され、秘密鍵またはパブリックで署名されますか?実際には、暗号化と署名の役割のために混乱します。簡単に言えば、暗号化が漏れることの情報を予防することである、と署名は、情報が改ざんされないようにすることです。2つの例を与えるために。
最初のシナリオ:戦場、B配信はコンテンツのメッセージ命令を与えます。
次のようにRSA暗号化プロセスは、次のとおりです。
(1)Aは、(公開鍵と秘密)鍵のペアを生成し、秘密鍵は、自身の予約が開示されていません。公開鍵は公開され、誰でも取得することができます。
(2)Aの公開鍵を用いて転送Bの公開鍵、Bは、メッセージを暗号化します。
(3)BのAは、暗号化されたメッセージを受信し、自分の秘密鍵Aを用いてメッセージを復号化
第1の公開鍵がBに伝達され、このプロセス、唯一の二次転写プロセスでは、Bは第2の暗号化されたメッセージは敵が傍受された場合でも、Aに送信され、民間だけので、危険は、ありませんメッセージ内容の開示を防ぐために、メッセージを復号化するキー。
第2のシナリオ:B Aは、送信されたメッセージを受信するには、返信する必要がある「受信します」。
次のようにRSA署名プロセスです。
(1)Aは、(公開鍵と秘密)鍵のペアを生成し、秘密鍵は、自身の予約が開示されていません。公開鍵は公開され、誰でも取得することができます。
(2)Aプラスメッセージの秘密鍵で署名、署名は、Bに沿ってそれ自体に承認メッセージとメッセージを形成し、
(3)Bがメッセージを受信した後、公開鍵Aは、テスト・メッセージは、それ自体のうち内容と一致している場合、チェックメッセージが応答であることを証明するために、テスト検査で取得しました。
このプロセスでは、唯一の二次転写プロセスは、最初の送信に加えAがメッセージに署名し、メッセージ自体Bに、Bは、取得した第2の公開鍵であり、敵が傍受されたとしても、危険がありません、唯一の秘密鍵は、彼らがメッセージの内容を知っていても、メッセージに署名することができますので、あなたがメッセージの内容の改ざんを防止するために、Bに署名した応答を偽造することはできません。
最初のシーンは、メッセージは明らかにしなかった傍受されましたが、偽のコマンドを暗号化するために、公開鍵を傍受するために使用することができ、その後、Aに渡されたものの、あなたは、総合的な2つのシナリオがあります 第2のシナリオは、傍受がメッセージを改ざんすることはできないが、公開鍵を使用して、メッセージの内容を取得するために署名され確認することができ、漏れを防止することができません。したがって、実際の応用では、使用する場合に応じて、暗号化と署名を同時に使用することができる、そのようなA及びBとしてBがAを与えるためにメッセージを送信した場合、公開鍵と秘密鍵の独自のセットを有し、Bの公開鍵と第メッセージの暗号化、およびその後、メッセージ暗号化された秘密鍵署名に使用し、リーチが開示されていないどちらも改ざんされて、私たちは、メッセージのセキュリティを保証することができます。
概要:公開鍵暗号、秘密鍵署名、公開鍵検査符号を復号化するための秘密鍵。
第三に、テストコード
RSAUtilツール
パブリッククラスRsaUtil {
/ **
* RSA暗号平文最大サイズ
* /
プライベート静的最終int型のMAX_ENCRYPT_BLOCK = 117;
/ **
* RSA暗号文の最大サイズを復号化
* /
プライベート静的最終int型のMAX_DECRYPT_BLOCK = 128;
public static final文字列privateKeyA = "privateKeyA"。
public static final文字列publicKeyA = "publicKeyA"。
public static final文字列publicKeyB = "publicKeyB"。
public static final文字列privateKeyB = "privateKeyB"。
/ **
*秘密鍵を取得します
* @ParamのPrivateKeyプライベート文字列
* @returnのPrivateKey
* /
パブリック静的のPrivateKey getPrivateKey(文字列のPrivateKey)は{例外をスロー
KeyFactoryにするKeyFactory = KeyFactory.getInstance( "RSA")。
バイト[] decodedKey = Base64.decodeBase64(privateKey.getBytes())。
あるPKCS8EncodedKeySpec keySpec =新しいあるPKCS8EncodedKeySpec(decodedKey)。
keyFactory.generatePrivate(keySpec)を返します。
}
/ **
*公開鍵を取得します
* @Param公開公共の文字列
* @returnのPublicKey
* /
パブリック静的のPublicKey getPublicKey(文字列公開)は{例外をスロー
KeyFactoryにするKeyFactory = KeyFactory.getInstance( "RSA")。
バイト[] decodedKey = Base64.decodeBase64(publicKey.getBytes())。
X509EncodedKeySpec keySpec =新しいX509EncodedKeySpec(decodedKey)。
keyFactory.generatePublic(keySpec)を返します。
}
/ **
*ランダムに生成された鍵ペア
* @throws持つNoSuchAlgorithmException
* /
パブリック静的地図<整数、文字列> genKeyPair()が持つNoSuchAlgorithmExceptionをスロー{
RSAアルゴリズムに基づいてオブジェクトを生成するために、公開鍵と秘密鍵を生成するための// KeyPairGeneratorクラス
するKeyPairGenerator keyPairGen = KeyPairGenerator.getInstance( "RSA")。
//は、鍵ペアジェネレータ、96から1024ビットのキーサイズを初期化します
keyPairGen.initialize(1024、新しいのSecureRandom());
//キーのペアは、鍵ペアに格納されて生成します
キーペア鍵ペア= keyPairGen.generateKeyPair()。
RSAPrivateKeyのPrivateKey =(RSAPrivateKey)keyPair.getPrivate(); //秘密鍵
RSAPublicKey公開=(のRSAPublicKey)keyPair.getPublic(); //公開鍵を取得します
文字列publicKeyString =新しいString(Base64.encodeBase64(publicKey.getEncoded()));
//プライベートキーの文字列を取得
文字列privateKeyString =新しいString(Base64.encodeBase64((privateKey.getEncoded())));
//地図に公開鍵と秘密鍵を保存
地図<整数、文字列>キーマップ=新しいHashMapの();
keyMap.put(0、publicKeyString); // 0は、公開鍵を表し、
keyMap.put(1、privateKeyString); // 1は、秘密鍵を表し、
キーマップを返します。
}
/ **
* RSA公開鍵暗号
* @Param strの文字列を暗号化
* @Param公開公衆
* @Return暗号文
* @throws例外例外メッセージの暗号化プロセス
* /
パブリック静的文字列の暗号化(文字列str、文字列公開)は{例外をスロー
// base64でエンコードされた公開鍵
バイト[] = Base64.decodeBase64(公開)デコード;
RSAPublicKey pubkeyで=(のRSAPublicKey)KeyFactory.getInstance( "RSA")のgeneratePublic(新しいX509EncodedKeySpec(デコード))。
// RSA暗号化
暗号暗号= Cipher.getInstance( "RSA")。
cipher.init(Cipher.ENCRYPT_MODE、pubkeyで)。
バイト[]データ=のstr.getBytes( "UTF-8");
int型inputLen = data.length。
ByteArrayOutputStreamアウト=新しいByteArrayOutputStream();
= 0のオフセットintです。
バイト[]キャッシュ。
int型私= 0;
//データセグメントを暗号化します
一方、(inputLen - > 0オフセット){
IF(inputLen - オフセット> MAX_ENCRYPT_BLOCK){
キャッシュ= cipher.doFinal(データ、オフセット、MAX_ENCRYPT_BLOCK)。
}他{
キャッシュ= cipher.doFinal(データ、オフセット、inputLen - オフセット)。
}
out.write(キャッシュ、0、cache.length)。
I ++;
オフセット=私はMAX_ENCRYPT_BLOCKを*;
}
バイト[]はEncryptedData = out.toByteArray()。
out.close();
ストリングoutStr = Base64.encodeBase64String(はEncryptedData)。
outStr返します。
}
/ **
* RSA秘密鍵復号化します
* @Param strの文字列を暗号化
* @ParamのPrivateKeyプライベート
* @Return碑文
* @throws例外例外メッセージの復号処理
* /
パブリック静的文字列の復号化(文字列str、文字列のPrivateKey)は{例外をスロー
// 64ビット暗号化された文字列をデコード
バイト[]データ= Base64.decodeBase64(str.getBytes( "UTF-8"));
// base64エンコードの秘密鍵
バイト[] = Base64.decodeBase64(のPrivateKey)デコード;
RSAPrivateKey priKey =(RSAPrivateKey)KeyFactory.getInstance( "RSA")generatePrivate(新しいあるPKCS8EncodedKeySpec(デコード))。
// RSA復号
暗号暗号= Cipher.getInstance( "RSA")。
cipher.init(Cipher.DECRYPT_MODE、priKey)。
int型inputLen = data.length。
ByteArrayOutputStreamアウト=新しいByteArrayOutputStream();
= 0のオフセットintです。
バイト[]キャッシュ。
int型私= 0;
//データセグメントを復号化します
一方、(inputLen - > 0オフセット){
IF(inputLen - オフセット> MAX_DECRYPT_BLOCK){
キャッシュ= cipher.doFinal(データ、オフセット、MAX_DECRYPT_BLOCK)。
}他{
キャッシュ= cipher.doFinal(データ、オフセット、inputLen - オフセット)。
}
out.write(キャッシュ、0、cache.length)。
I ++;
オフセット=私はMAX_DECRYPT_BLOCKを*;
}
バイト[] decryptedData = out.toByteArray()。
out.close();
文字列outStr =新しいString(decryptedData)。
outStr返します。
}
/ **
*署名
* @Paramデータデータが署名されます
* @ParamのPrivateKeyプライベート
* @Return署名
* /
パブリック静的文字列の記号(文字列データ、のPrivateKeyのPrivateKey)は{例外をスロー
バイト[] keyBytes = privateKey.getEncoded()。
あるPKCS8EncodedKeySpec keySpec =新しいあるPKCS8EncodedKeySpec(keyBytes)。
KeyFactoryにするKeyFactory = KeyFactory.getInstance( "RSA")。
PrivateKeyのキー= keyFactory.generatePrivate(keySpec)。
署名署名= Signature.getInstance( "MD5withRSA")。
signature.initSign(キー);
signature.update(data.getBytes())。
新しいStringを返す(Base64.encodeBase64(signature.sign()));
}
/ **
*検証印
* @Param srcData元の文字列
* @Param公開公衆
* @Paramサイン署名
* @Returnチェック検査によってか
* /
パブリック静的ブール(文字列srcData、のPublicKey公開、文字列記号)検証は例外をスロー{
バイト[] keyBytes = publicKey.getEncoded()。
X509EncodedKeySpec keySpec =新しいX509EncodedKeySpec(keyBytes)。
KeyFactoryにするKeyFactory = KeyFactory.getInstance( "RSA")。
公開鍵キー= keyFactory.generatePublic(keySpec)。
署名署名= Signature.getInstance( "MD5withRSA")。
signature.initVerify(キー);
signature.update(srcData.getBytes())。
リターンsignature.verify(Base64.decodeBase64(sign.getBytes()));
}
}
Testクラスのクライアント
以下を使用するためのツールとして、民間、公共の2ペアを生成すると仮定
パブリッククラスTestClient {
パブリック静的無効メイン(文字列[] args){
サーバーは//クライアントBであります
//テスト記号()。
// testPassword();
testSignAndPassword();
}
パブリック静的ボイドtestPassword(){
テストサーバーのテストサーバー=新しいテストサーバー();
{試します
PasswordOrder passwordOrder =新しいPasswordOrder( "1"、新たなBigDecimalを(100)、 "描述信息"、 "weixin")。
System.out.println( "暗号化前のデータ:" + JSONObject.toJSONString(passwordOrder));
文字列を暗号化= RsaUtil.encrypt(JSONObject.toJSONString(passwordOrder)、RsaUtil.publicKeyA)。
System.out.println( "暗号化されたデータ:" +暗号化);
testServer.testPassword(暗号化)。
}キャッチ(例外e){
e.printStackTrace();
}
}
パブリック静的ボイドtestSign(){
{試します
テストサーバーのテストサーバー=新しいテストサーバー();
ClientOrder順序=新しいClientOrder( "1"、新たなBigDecimalを(100)、 "説明"、 "weixin")。
文字列データ= MapUtil.mapToString(MapUtil.beanToMap(順序))。
文字列記号= RsaUtil.sign(データ、RsaUtil.getPrivateKey(RsaUtil.privateKeyA))。
order.setSign(記号)
System.out.println(「元データへのクライアント要求データと署名:」+ JSONObject.toJSONString(オーダー));
testServer.testSign(オーダー)
}キャッチ(例外e){
e.printStackTrace();
}
}
/ **
*最初の署名後、それがサーバに暗号文の広がりを暗号化し、
* /
パブリック静的ボイドtestSignAndPassword(){
{試します
テストサーバーのテストサーバー=新しいテストサーバー();
ClientOrder順序=新しいClientOrder( "1"、新たなBigDecimalを(100)、 "説明"、 "weixin")。
文字列データ= MapUtil.mapToString(MapUtil.beanToMap(順序))。
文字列記号= RsaUtil.sign(データ、RsaUtil.getPrivateKey(RsaUtil.privateKeyA))。
order.setSign(記号)
System.out.println( "署名:" +記号)。
System.out.println( "暗号化前のデータ:" + JSONObject.toJSONString(オーダー));
文字列を暗号化= RsaUtil.encrypt(JSONObject.toJSONString(順序)、RsaUtil.publicKeyB)。
System.out.println( "暗号化されたデータ:" +暗号化);
testServer.testSignAndPassword(暗号化)。
}キャッチ(例外e){
e.printStackTrace();
}
}
}
Testクラスサーバー
パブリッククラスTESTSERVER {
公共ボイドtestSign(ClientOrder順序){
{試します
System.out.println( "受信データサーバ:" + JSONObject.toJSONString(オーダー));
文字列記号= order.getSign()。
order.setSign(NULL)。
文字列データ= MapUtil.mapToString(MapUtil.beanToMap(順序))。
ブール= RsaUtil.verify(データ、RsaUtil.getPublicKey(RsaUtil.publicKeyA)、署名)を検証します。
System.out.println(「テスト投票結果:」+検証)。
}キャッチ(例外e){
e.printStackTrace();
}
}
公共のボイドtestPassword(文字列の暗号化){
{試します
文字列解読= RsaUtil.decrypt(暗号化、RsaUtil.privateKeyA)。
PasswordOrder passwordOrder = JSONObject.parseObject(PasswordOrder.classを解読)。
System.out.println( "復号化されたデータ:" + JSONObject.toJSONString(passwordOrder));
}キャッチ(例外e){
e.printStackTrace();
}
}
/ **
*復号化、署名した後、検査
* @paramの暗号化
* /
公共のボイドtestSignAndPassword(文字列の暗号化){
{試します
System.out.println( "データ受付:" +暗号化);
文字列解読= RsaUtil.decrypt(暗号化、RsaUtil.privateKeyB)。
System.out.println( "復号化されたデータ:" +復号化)。
ClientOrder clientOrder = JSONObject.parseObject(ClientOrder.classを解読)。
文字列記号= clientOrder.getSign()。
clientOrder.setSign(NULL)。
文字列データ= MapUtil.mapToString(MapUtil.beanToMap(clientOrder))。
ブール= RsaUtil.verify(データ、RsaUtil.getPublicKey(RsaUtil.publicKeyA)、署名)を検証します。
System.out.println(「テスト投票結果:」+検証)。
}キャッチ(例外e){
e.printStackTrace();
}
}
}
注意:
1、それはセグメント化され、暗号化と復号化に使用されるべき場合、RSA暗号化および復号化は、長さの制限がある場合ため。
暗号化と復号化最初の署名暗号化の後に時間を使用する必要が要求Bは、Bは、受信A、次にB、公開鍵暗号、最終パスの暗号文Bの秘密鍵を用いて生成された署名であると仮定しなければならない2、暗号文は、Bの秘密鍵で復号化されると、その後、公衆の閲覧に署名しています。
使用シナリオ:
1、暗号化されたデータのみ、サーバ側は、公開鍵と秘密鍵のペアを生成し、このときだけは、主にこのような場合に使用されるクライアントへの公開鍵は、パスワード等のパスなど、Webサーバと対話します。(アンチ漏れ)
図2に示すように、符号のみデータは、唯一のこの時間は、クライアント側は公開鍵と秘密鍵のペアを生成し、サーバに公開鍵が、これは主に企業内および第三の交配に使用され、例えば、企業は、マイクロチャネルアクセスに必要な項目を有しますアリペイ、Jingdongは、すなわち、Aがクライアントである、それはそう、サードパーティのコールの後に毎回、第三者に、署名データを必要とし、その後、検査記号を実行するために、サードパーティ製のサーバです。(タンパープルーフ)
図3に示すように、データは、クライアントとサーバーのそれぞれの両方が公開鍵と秘密鍵、公開鍵の交換のペアを生成し、署名および暗号化され、これは、主に二つの企業が通信するためにそのような酢酸メチルとして、企業間のデータ転送に使用されます。(耐タンパ性と漏れ防止)
これらは、参照データであり、元の対象と自分の利益は、ご了承ください!