Javaの下でいくつかの暗号化方式の実現
9643 ワード
最近ずっとこの方面のものをして、先に実現を置いて、原理はゆっくりと補います.
Mavenライブラリ
jdk自体の復号アルゴリズムが不完全であるため、以下の2つのライブラリのサポートを追加する必要があります.
AES
可逆的なアルゴリズムであって、原文は鍵のセットによって暗号化され、その後、この鍵によって復元されることができる.
SHA
MD 4の発展に基づいて不可逆的なhashアルゴリズムのセットが得られた.
RSA
非対称暗号化方式であって、鍵は2つのバイナリデータを有し、1つは公開鍵とし、1つは秘密鍵とし、バイナリのデータはそのうちの1つの鍵で暗号化され、その後、別の鍵で復号される.
発生する可能性のあるエラー
復号化中にこのエラーが発生する可能性があります
これは、いくつかの法律法規の制限により、jdkソースパケットにおける暗号化の強度が低下するためである.
この問題を解決するには、Oracle Webサイトから圧縮ファイルをダウンロードします. JDK6: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html JDK7: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
このパッケージを解凍して、中の2つのjarパッケージ:local_义齿export_policy.jar元Javaインストールディレクトリ{JAVA_HOME}/jre/lib/securityの下にある2つのjarパッケージを置き換えればよい.
Mavenライブラリ
jdk自体の復号アルゴリズムが不完全であるため、以下の2つのライブラリのサポートを追加する必要があります.
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk16</artifactId>
<version>1.46</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
AES
可逆的なアルゴリズムであって、原文は鍵のセットによって暗号化され、その後、この鍵によって復元されることができる.
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.util.encoders.Hex;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
public class AESCoder {
public static final String KEY_ALGORITHM = "AES";
public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
//
private static Key toKey(byte[] key) throws Exception{
// DES
SecretKey secretKey = new SecretKeySpec(key,KEY_ALGORITHM);
return secretKey;
}
//
public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
//
Key k = toKey(key);
//
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
// ,
cipher.init(Cipher.DECRYPT_MODE,k);
//
return cipher.doFinal(data);
}
//
public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
//
Key k = toKey(key);
//
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,k);
//
return cipher.doFinal(data);
}
//
public static byte[] initKey() throws Exception{
//
KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
// 256
kg.init(256);
//
SecretKey secretKey = kg.generateKey();
//
return secretKey.getEncoded();
}
public static void main(String args[]) throws Exception{
String str = "AES" ;
byte[] inputData = str.getBytes();
System.out.println(" :"+str);
//
byte[] key = AESCoder.initKey();
System.out.println(" :"+ Base64.encodeBase64String(key));
//
inputData = AESCoder.encrypt(inputData,key);
System.out.println(" :"+ new String(Hex.encode(inputData)));
//
byte[] outputData = AESCoder.decrypt(inputData,key);
String outstr = new String(outputData);
System.out.println(outstr);
}
}
SHA
MD 4の発展に基づいて不可逆的なhashアルゴリズムのセットが得られた.
import org.bouncycastle.util.encoders.Hex;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class SHACoder {
//SHA-256
public static byte[] encodeSHA(byte[] data){
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
return md.digest(data);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
// 16
public static String encodeSHAHex(byte[] data){
byte[] b = encodeSHA(data);
return new String(Hex.encode(b));
}
}
RSA
非対称暗号化方式であって、鍵は2つのバイナリデータを有し、1つは公開鍵とし、1つは秘密鍵とし、バイナリのデータはそのうちの1つの鍵で暗号化され、その後、別の鍵で復号される.
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
public class RSACoder {
public static final String KEY_ALGORITHM = "RSA";
//
private static final String PUBLIC_KEY = "RSAPublicKey";
//
private static final String PRIVATE_KEY = "RSAPrivateKey";
//RSA
// 1024
// 64
// 512 ~ 65536
private static final int KEY_SIZE = 1024 ;
//
public static byte[] decryptByPrivateKey(byte[] data,byte[] key) throws Exception{
//
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE,privateKey);
return cipher.doFinal(data);
}
//
public static byte[] decryptByPublicKey(byte[] data,byte[] key) throws Exception{
//
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
//
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE,publicKey);
return cipher.doFinal(data);
}
//
public static byte[] encryptByPrivateKey(byte[] data,byte[] key) throws Exception{
//
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE,privateKey);
return cipher.doFinal(data);
}
//
public static byte[] encryptByPublicKey(byte[] data,byte[] key) throws Exception{
//
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//
PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
//
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
return cipher.doFinal(data);
}
//
public static byte[] getPriavteKey(Map<String,Object> keymap) throws Exception{
Key key = (Key)keymap.get(PRIVATE_KEY);
return key.getEncoded();
}
//
public static byte[] getPublicKey(Map<String,Object> keymap) throws Exception {
Key key = (Key)keymap.get(PUBLIC_KEY);
return key.getEncoded();
}
//
public static Map<String,Object> initKey() throws Exception{
//
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//
keyPairGen.initialize(KEY_SIZE);
//
KeyPair keyPair = keyPairGen.generateKeyPair();
//
RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
//
RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
//
Map<String,Object> keyMap = new HashMap<>(2);
keyMap.put(PUBLIC_KEY,publicKey);
keyMap.put(PRIVATE_KEY,privateKey);
return keyMap;
}
public static void main(String args[]) throws Exception{
//
Map<String,Object> keymap = RSACoder.initKey();
byte[] publickey = RSACoder.getPublicKey(keymap);
byte[] privatekey = RSACoder.getPriavteKey(keymap);
System.out.println(Base64.encodeBase64String(publickey));
System.out.println(Base64.encodeBase64String(privatekey));
//
// ,
String inputstr = "whthomas";
//
byte[] encodedeData1 = RSACoder.encryptByPrivateKey(inputstr.getBytes(),privatekey);
System.out.println(Base64.encodeBase64String(encodedeData1));
//
byte[] decodedeData1 = RSACoder.decryptByPublicKey(encodedeData1,publickey);
System.out.println(new String(decodedeData1));
// ,
//
byte[] encodedeData2 = RSACoder.encryptByPublicKey(inputstr.getBytes(), publickey);
System.out.println(Base64.encodeBase64String(encodedeData2));
//
byte[] decodedeData2 = RSACoder.decryptByPrivateKey(encodedeData2, privatekey);
System.out.println(new String(decodedeData2));
}
}
発生する可能性のあるエラー
復号化中にこのエラーが発生する可能性があります
Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
これは、いくつかの法律法規の制限により、jdkソースパケットにおける暗号化の強度が低下するためである.
この問題を解決するには、Oracle Webサイトから圧縮ファイルをダウンロードします.
このパッケージを解凍して、中の2つのjarパッケージ:local_义齿export_policy.jar元Javaインストールディレクトリ{JAVA_HOME}/jre/lib/securityの下にある2つのjarパッケージを置き換えればよい.