まず、簡単な暗号化を見て、復号化が実現します
1.1暗号化
/ ** *内容:暗号化されたコンテンツ * slatKey:暗号塩、16ビットのビット列 * vectorKey:暗号ベクトル、16ビットのビット列 * / パブリック文字列暗号化(文字列コンテンツ、slatKey文字、文字列vectorKey)をスロー例外{ 暗号暗号を Cipher.getInstance =( "AES / CBC / PKCS5Padding"変換); 秘密鍵秘密鍵 = 新しい新しい SecretKeySpec(slatKey.getBytes()、 "AES" ); IvParameterSpec IV = 新たな新しいIvParameterSpec(vectorKey.getBytes()); cipher.init(暗号。 ENCRYPT_MODE、秘密鍵、IV); バイト [] = ENCRYPTED Cipher.doFinal(content.getBytes()); リターンBase64.encodeBase64String(暗号化); }
1.2解読
/ ** *コンテンツ:コンテンツ(Base64エンコード形式)を復号 * slatKey:暗号化に使用される塩、16ビットのビット列 * vectorKey:暗号化に使用されるベクター、16ビットのビット列 * / パブリック文字列の復号化(base64Content文字、文字列slatKey 、文字列vectorKey)をスロー例外{ 暗号暗号( "AES / CBC / PKCS5Padding"変換= Cipher.getInstance ;) 秘密鍵秘密鍵 = 新しい新しい SecretKeySpec(slatKey.getBytes()、 "AES" ); IvParameterSpec IV = 新たな新しいIvParameterSpec(vectorKey.getBytesを( )); cipher.init(Cipher.DECRYPT_MODE、秘密鍵、IV); バイト []コンテンツ= Base64.decodeBase64(base64Content) バイト[] =暗号化cipher.doFinal(コンテンツ)。 返す 新しい文字列を(暗号化); }
1.3コード説明
暗号化と復号化簡単に実現AES( "AES / CBC / PKCS5Padding" 変換)上記。私たちは、コードは次の呼び出しで、主に暗号オブジェクトで見ることができます
(1)パラメータ「AES / CBC / PKCS5Padding」変換の新しいオブジェクト暗号を渡す必要があります
(2)暗号の使用前に初期化に必要なオブジェクト、三つのパラメータの合計(「暗号化モードあるいは復号化モード」、「キー」、「ベクター」)
(3)コールのデータ変換:cipher.doFinal(コンテンツ)、コンテンツのバイト配列であります
実際にはCipherクラスを使用すると、Cipherオブジェクトを作成するときに、異なるパラメータを渡すと異なる暗号化アルゴリズムすることができ、様々な暗号化アルゴリズムを実装しています。そして、ちょうどキーアルゴリズムを作成するために、これらのさまざまな場所で異なっています。
入ってくる "AES / CBC / NoPadding" AES暗号化を行うことができ、入ってくる "DESEDE / CBC / NoPaddingは" DES3暗号化することができます。特定のは、背後に導入されます。
内蔵の暗号化アルゴリズムのJavaを参照するには、JDKのドキュメントは、付録を参照してください可能性がありますhttps://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html
二、Javaの暗号クラス
2.1 Cipherクラスは、暗号化と復号化機能を提供します。
このプロジェクトは、Cipherクラス完了AES、DES、DES3とRSA暗号化を使用しています。
ようにパラメータ「アルゴリズム/モード/モードを埋める」次のパラメータを有し、暗号暗号= Cipher.getInstance(「DES / CBC / PKCS5Padding」変換):暗号クラスオブジェクトを取得
* AES / CBC / NoPadding(128)
* AES / CBC / PKCS5Padding(128)
* AES / ECB / NoPadding(128)
* AES / ECB / PKCS5Padding(128)
* DES / CBC / NoPadding(56で)
* DES / CBC / PKCS5Padding(56である)
* DES / ECB / NoPadding(56である)
* DES / ECB / PKCS5Padding(56である)
* DESEDE / CBC / NoPadding(168)
* DESEDE / CBC / PKCS5Padding(168)
* DESEDE / ECB / NoPadding(168)
* DESEDE / ECB / PKCS5Padding(168)
* RSA / ECB / PKCS1Padding(1024、2048)
* RSA / ECB / OAEPWithSHA-1AndMGF1Padding(1024、2048)
* RSA / ECB / OAEPWithSHA-256AndMGF1Padding(1024、2048)
(1)暗号化アルゴリズムあり:AES、DES、DESEDE(DES3 ) とRSAの4種類
(ベクトルモードで)CBCモード(2)及びECB(NOベクトルモード)は、ベクトルモードは、オフセット簡単として理解することができる、CBCモードが定義されてIvParameterSpecが必要オブジェクト
(3)モードを入力します。
* NoPadding:暗号化されたコンテンツがゼロ8と8未満であるCipherクラスは、ビットの機能を提供していない、それらの実装コードは、暗号化されたコンテンツ0を追加するために必要な、{など} 65,65,65,0,0,0,0,0
* PKCS5Padding:暗号化されたコンテンツは、{97,97,97,97,97,97,2 65,65,65,5,5,5,5,5例えば} {として、より多くの8ビットで構成された、8未満であるか、または2};ちょうど埋める8 8 8
2.2 Cipherオブジェクトを初期化する必要があります
INIT(int型OPMODE、キーキー、のAlgorithmParameterSpec paramsは)
OPMODE(1):Cipher.ENCRYPT_MODE(暗号化モード)とCipher.DECRYPT_MODE(復号モード)
(2)キー:塩構築パス・キーを使用してキーあなたはSecretKeySpec、するKeyGeneratorとするKeyPairGenerator、使用するキーを作成することができます
* SecretKeySpecとするKeyGeneratorサポートAES、DES、DESEDE 3つの暗号化アルゴリズムは、キーを作成するための
キーを作成する* KeyPairGeneratorのサポートRSA暗号化アルゴリズム
(3)のparams:CBCモードを使用するときに渡す必要がありますがプロジェクトの静脈オブジェクトのパラメータはIvParameterSpecを使用して作成しました
2.3暗号化や復号化
バイト[] B = cipher.doFinal(コンテンツ );
戻り結果のバイト配列、新たな文字列(b)は、文字列中にカプセル化として使用される場合、歪みが発生
第三に、キーを作成します
メインキーは、キーを作成するSecretKeySpec、するKeyGeneratorやKeyPairGeneratorの三つのクラスを使用して作成されます。
3.1 SecretKeySpecクラス
SecretKeySpecクラスは、鍵暗号化アルゴリズム(ASE、DES、DES3)の作成をサポートしています
SecretKey秘密鍵= 新しい SecretKeySpec(slatKey.getBytes()、 "AES");
しかし、主なものは、異なる暗号化アルゴリズムの必要なバイト配列の長さは、異なっている次のバイト配列の前にキーの長さを検出するために、良いアイデアを作成することです。次のように各キーの暗号化アルゴリズムの長さがあります
暗号化アルゴリズム | キーの長さ | ベクトル長 |
AES | 16 | 16 |
OF | 8 | 8 |
DES3 | 24 | 8 |
3.2のKeyGenerator类
KeyGeneratorクラスは、鍵暗号化アルゴリズム(ASE、DES、DES3)の作成をサポートしています
/** * 获取加密的密匙,传入的slatKey可以是任意长度的,作为SecureRandom的随机种子, * 而在KeyGenerator初始化时设置密匙的长度128bit(16位byte) */ private static Key getSlatKey(String slatKey) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance("AES"); SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed(slatKey.getBytes()); kgen.init(128, random); Key key = kgen.generateKey(); return key; }
KeyGenerator对象在初始化需要传入一个随机源。一般使用的都是SecureRandom类来创建随机源,此时传入的盐只作为SecureRandom类的随机种子,种子相同,产生的随机数也相同;
盐的长度不再受限制了,但KeyGenerator对象则必须指定长度。
3.3KeyPairGenerator类
RSA加密算法使用的密匙是包含公匙和私匙两种,一般情况下,有使用公匙加密,则用私匙解密;使用私匙加密,则使用公匙解密。可以使用KeyPairGenerator类来创建RSA加密算法的密匙
KeyPairGenerator类支持创建密匙的加密算法(RSA)
/** * 根据slatKey获取公匙,传入的slatKey作为SecureRandom的随机种子 * 若使用new SecureRandom()创建公匙,则需要记录下私匙,解密时使用 */ private static byte[] getPublicKey(String slatKey) throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed(slatKey.getBytes()); keyPairGenerator.initialize(1024, random);//or 2048 KeyPair keyPair = keyPairGenerator.generateKeyPair(); return keyPair.getPublic().getEncoded(); } /** * 根据slatKey获取私匙,传入的slatKey作为SecureRandom的随机种子 */ private static byte[] getPrivateKey(String slatKey) throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); random.setSeed(slatKey.getBytes()); keyPairGenerator.initialize(1024, random);// or 2048 KeyPair keyPair = keyPairGenerator.generateKeyPair(); return keyPair.getPrivate().getEncoded(); }
同上,传入的盐只作为SecureRandom类的随机种子,盐相同,产生的keyPair的公匙和私匙也是同一对。
也可以不设置SecureRandom类的随机种子,直接使用new SecureRandom()创建一个新对象,此时就必须记录下公匙和私匙,在解密时使用。
四、对加密结果进行一层包装
4.1 针对1.3返回结果返回字符串乱码的问题,一般对byte数组进行处理
有两种处理方式:转换为base64的字符串或转换为16进制的字符串
4.2 转换为base64
使用apache下的Base64类进行封装即可,Base64.encodeBase64String(result); 结果形如 qPba5V+b0Ox3Um...
jar包下载:https://mvnrepository.com/artifact/commons-codec/commons-codec
4.3 转换为16进制
编码实现,即编码实现将2进制转换为16进制
/** * 16进制工具类 */ public class HexUtil { private static final char[] HEX_CHARS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /** * 十六进制转化为二进制 */ public static byte[] hexStrToByteArray(String hexString) { if (hexString == null) { return null; } if (hexString.length() == 0) { return new byte[0]; } byte[] byteArray = new byte[hexString.length() / 2]; for (int i = 0; i < byteArray.length; i++) { String subStr = hexString.substring(2 * i, 2 * i + 2); byteArray[i] = ((byte) Integer.parseInt(subStr, 16)); } return byteArray; } /** * 二进制转化为十六进制 */ public static String byteArrayToHexStr(byte[] byteArray) { if (byteArray == null) { return null; } char[] hexChars = new char[byteArray.length * 2]; for (int j = 0; j < byteArray.length; j++) { int v = byteArray[j] & 0xFF; hexChars[j * 2] = HEX_CHARS[v >>> 4]; hexChars[j * 2 + 1] = HEX_CHARS[v & 0x0F]; } return new String(hexChars); } }
结果形如 04A2784A45234B.....
五、Java加密的代码
代码我上传到github上了,欢迎下载~~