1均芽、BASE64
BASE64嚴(yán)格地說,應(yīng)該說是屬于編碼格式单鹿,而非加密算法掀宋。
加解密:
/**
* 加密
*/
public static String encryptBASE64(byte[] data) {
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);
}
/**
* 解密
*/
public static byte[] decryptBASE64(String cipher) {
BASE64Decoder decoder = new BASE64Decoder();
byte[] bytes = null;
try {
bytes = decoder.decodeBuffer(cipher);
} catch (IOException e) {
e.printStackTrace();
}
return bytes;
}
2、MD5和SHA
MD5(Message Digest algorithm 5仲锄,信息摘要算法)劲妙,常用于文件校驗。
SHA(Secure Hash Algorithm儒喊,安全散列算法)镣奋,同樣屬于非可逆的算法,作用與MD5相類似怀愧。
MD5輸出是128位的侨颈,SHA輸出是160位的。SHA相較于MD5而言更加安全芯义,當(dāng)然加密花費時間也更長一點哈垢。
先設(shè)置常量
private final static String KEY_SHA = "SHA";
private final static String KEY_MD5 = "MD5";
加密
/**
* MD5加密
*/
public static String encryptMD5(byte[] data) {
String cipher = null;
try {
MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
md5.update(data);
cipher = encryptBASE64(md5.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return cipher;
}
/**
* SHA加密
*/
public static String encryptSHA(byte[] data) {
String cipher = null;
try {
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
sha.update(data);
cipher = encryptBASE64(sha.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return cipher;
}
3、RSA
RSA算法是一種非對稱密碼算法扛拨。詳情見RSA算法
)
設(shè)置需要用到常量,RSA_INIT_LENGTH
為密鑰的初始化長度耘分,密鑰的長度越長,安全性就越好,但是加密解密所用的時間就會越多求泰。一次能加密的密文長度為:密鑰的長度/8-11央渣。所以1024bit長度的密鑰一次可以加密的密文為1024/8-11=117bit。所以非對稱加密一般都用于加密對稱加密算法的密鑰渴频,而不是直接加密內(nèi)容芽丹。對于小文件可以使用RSA加密,但加密過程仍可能會使用分段加密枉氮。
private final static String KEY_RSA = "RSA";
private final static int RSA_INIT_LENGTH = 1024;
3.1志衍、java中初始化生成公鑰和私鑰
/**
* 初始化
*/
public static String[] initRSAKey() {
String[] keys = null;
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_RSA);
keyPairGenerator.initialize(RSA_INIT_LENGTH);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 公鑰
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私鑰
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
keys = new String[]{encryptBASE64(publicKey.getEncoded()), encryptBASE64(privateKey.getEncoded())};
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return keys;
}
3.2、加解密
RSA有兩個密鑰聊替,所以加解密方式也有兩種楼肪,一種是“私鑰加密-公鑰解密”,另一種就是“公鑰加密-私鑰解密”惹悄,加解密的實現(xiàn)如下:
/**
* 私鑰加密
*/
public static byte[] encryptByPrivateKey(byte[] data, String key) {
try {
byte[] keyBytes = decryptBASE64(key);
// 獲得私鑰
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
// 對數(shù)據(jù)加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 公鑰解密
*/
public static byte[] decryptByPublicKey(byte[] data, String key) {
try {
// 對私鑰解密
byte[] keyBytes = decryptBASE64(key);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
// 對數(shù)據(jù)解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 公鑰加密
*/
public static byte[] encryptByPublicKey(byte[] data, String key) {
try {
// 對公鑰解密
byte[] keyBytes = decryptBASE64(key);
// 取公鑰
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
Key publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
// 對數(shù)據(jù)解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 私鑰解密
*/
public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
try {
// 對私鑰解密
byte[] keyBytes = decryptBASE64(key);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
Key privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
// 對數(shù)據(jù)解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
3.3 簽名驗證
使用RSA進行簽名驗證春叫。數(shù)字簽名技術(shù)是將摘要信息用發(fā)送者的私鑰加密,與原文一起傳送給接收者泣港。接收者只有用發(fā)送者的公鑰才能解密被加密的摘要信息暂殖,然后用對收到的原文產(chǎn)生一個摘要信息,與解密的摘要信息對比当纱。如果相同呛每,則說明收到的信息是完整的,在傳輸過程中沒有被修改坡氯,否則說明信息被修改過晨横,因此數(shù)字簽名能夠驗證信息的完整性。
該方法可行有兩個的條件:
1箫柳、通過公鑰推算出私鑰的做法不可能實現(xiàn)
2手形、即使傳輸數(shù)據(jù)的過程被攔截,因為攔截者沒有私鑰悯恍,改動數(shù)據(jù)就會導(dǎo)致簽名的不一致库糠。(這里需要注意,攔截者還是可以使用公鑰對數(shù)據(jù)進行解密涮毫,看到傳輸?shù)臄?shù)據(jù)的)
定義常量
private final static String RSA_MD5 = "MD5withRSA";
簽名和簽名驗證
/**
* 私鑰簽名
*/
public static String signByPrivateKey(byte[] data, String privateKey) {
try {
// 解密私鑰
byte[] keyBytes = decryptBASE64(privateKey);
// 構(gòu)造PKCS8EncodedKeySpec對象
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
// 指定加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
// 取私鑰匙對象
PrivateKey privateKey2 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
// 用私鑰對信息生成數(shù)字簽名
Signature signature = Signature.getInstance(RSA_MD5);
signature.initSign(privateKey2);
signature.update(data);
return encryptBASE64(signature.sign());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 公鑰驗證
*/
public static boolean verifyByPublicKey(byte[] data, String publicKey, String sign) {
try {
// 解密公鑰
byte[] keyBytes = decryptBASE64(publicKey);
// 構(gòu)造X509EncodedKeySpec對象
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyBytes);
// 指定加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_RSA);
// 取公鑰匙對象
PublicKey publicKey2 = keyFactory.generatePublic(x509EncodedKeySpec);
Signature signature = Signature.getInstance(RSA_MD5);
signature.initVerify(publicKey2);
signature.update(data);
// 驗證簽名是否正常
return signature.verify(decryptBASE64(sign));
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
4瞬欧、DES
DES(全稱為DataEncryption Standard,即數(shù)據(jù)加密標(biāo)準(zhǔn))罢防,是一種對稱加密算法黍判!
定義常量
private final static String KEY_DES = "DES";
加解密,其中key是8位的密碼
/**
* 加密
*/
public static byte[] encryptDES(byte[] data, String key) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);
SecretKey secureKey = keyFactory.generateSecret(desKey);
Cipher cipher = Cipher.getInstance(KEY_DES);
cipher.init(Cipher.ENCRYPT_MODE, secureKey, random);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 解密
*/
public static byte[] decryptDES(byte[] data, String key) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_DES);
SecretKey secureKey = keyFactory.generateSecret(desKey);
Cipher cipher = Cipher.getInstance(KEY_DES);
cipher.init(Cipher.DECRYPT_MODE, secureKey, random);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}