对称加密算法是应用较早的加密算法,技术成熟。在对称加密算法中,数据发信方将明文(原始数据)和加密密钥一块儿通过特殊加密算法处理后,使其变成复杂的加密密文发送出去。收信方收到密文后,若想解读原文,则须要使用加密用过的密钥及相同算法的逆算法对密文进行解密,才能使其恢复成可读明文。在对称加密算法中,使用的密钥只有一个,发收信双方都使用这个密钥对数据进行加密和解密,这就要求解密方事先必须知道加密密钥。java
对称加密算法的优势是:算法公开、计算量小、加密速度快、加密效率高。缺点是:首先,交易双方都使用一样钥匙,安全性得不到保证。其次,每对用户每次使用对称加密算法时,都须要使用其余人不知道的唯一钥匙,这会使得发收信双方所拥有的钥匙数量呈几何级数增加,密钥管理成为用户的负担。对称加密算法在分布式网络系统上使用较为困难,主要是由于密钥管理困难,使用成本较高。算法
DES算法是最流行的对称加密算法,全称是Data Encryption Standard,即数据加密算法,它是IBM公司于1975年研究成功并公开发表的。DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工做密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工做方式,有两种:加密或解密。编程
能够对数据进行三次DES算法,从而造成3DES算法。此算法至关因而对每一个数据块应用三次DES加密算法。因为计算机运算能力的加强,原版DES密码的密钥长度变得容易被暴力破解;3DES便是设计用来提供一种相对简单的方法,即经过增长DES的密钥长度来避免相似的攻击,而不是设计一种全新的块密码算法。对此算法的介绍,本文后面再也不赘述。数组
a.算法原理安全
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位,其算法主要分为两步:网络
1.初始置换框架
其功能是把输入的64位数据块按位从新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则通过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7。dom
2.逆置换编程语言
通过16次迭代运算后,获得L1六、R16,将此做为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即获得密文输出。分布式
b.DES算法在Java中的实现及运用
Java中为安全框架提供类和接口。JDK 安全 API 是 Java 编程语言的核心 API,位于 java.security 包(及其子包),以及sun.securityAPI包(及其子包)中。设计用于帮助开发人员在程序中同时使用低级和高级安全功能。
应用实例:
private static int parse(char c) {
if (c >= 'a')
return (c - 'a' + 10) & 0x0f;
if (c >= 'A')
return (c - 'A' + 10) & 0x0f;
return (c - '0') & 0x0f;
}
// 从十六进制字符串到字节数组转换
public static byte[] HexString2Bytes(String hexstr) {
byte[] b = new byte[hexstr.length() / 2];
int j = 0;
for (int i = 0; i < b.length; i++) {
char c0 = hexstr.charAt(j++);
char c1 = hexstr.charAt(j++);
b[i] = (byte) ((parse(c0) << 4) | parse(c1));
}
return b;
}
private static SecretKey keyGenerator(String keyStr) throws Exception {
byte input[] = HexString2Bytes(keyStr);
DESKeySpec desKey = new DESKeySpec(input);
// 建立一个密匙工厂,而后用它把DESKeySpec转换成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
return securekey;
}
// 加密
public static String encrypt(String data, String key) throws Exception {
Key deskey = keyGenerator(key);
// 实例化Cipher对象,它用于完成实际的加密操做
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
SecureRandom random = new SecureRandom();
// 初始化Cipher对象,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, deskey, random);
byte[] results = cipher.doFinal(data.getBytes());
// 执行加密操做。加密后的结果一般都会用Base64编码进行传输
return Base64.encodeBase64String(results);
}
// 解密
public static String decrypt(String data, String key) throws Exception {
Key deskey = keyGenerator(key);
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
// 初始化Cipher对象,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, deskey);
// 执行解密操做
return new String(cipher.doFinal(Base64.decodeBase64(data)));
}
非对称加密算法的核心源于数学问题,它存在公钥和私钥的概念,要完成加解密操做,须要两个密钥同时参与。
非对称密码体制的特色:算法强度复杂、安全性依赖于算法与密钥可是因为其算法复杂,而使得加密解密速度没有对称加密解密的速度快。对称密码体制中只有一种密钥,而且是非公开的,若是要解密就得让对方知道密钥。因此保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就能够不须要像对称密码那样传输对方的密钥了。这样安全性就大了不少。
RSA加密算法是一种典型的非对称加密算法,它基于大数的因式分解数学难题,它也是应用最普遍的非对称加密算法,于1978年由美国麻省理工学院(MIT)的三位学着:Ron Rivest、Adi Shamir 和 Leonard Adleman 共同提出。
a.算法原理
RSA的原理较为简单。咱们假设有消息发送方A和消息接收方B,经过下面的几个步骤,咱们就能够完成消息的加密传递:
1)消息发送方A在本地构建密钥对,公钥和私钥;
2)消息发送方A将产生的公钥发送给消息接收方B;
3)B向A发送数据时,经过公钥进行加密,A接收到数据后经过私钥进行解密,完成一次通讯;
4)反之,A向B发送数据时,经过私钥对数据进行加密,B接收到数据后经过公钥进行解密。
因为公钥是消息发送方A暴露给消息接收方B的,因此这种方式也存在必定的安全隐患,若是公钥在数据传输过程当中泄漏,则A经过私钥加密的数据就可能被解密。
若是要创建更安全的加密消息传递模型,须要消息发送方和消息接收方各构建一套密钥对,并分别将各自的公钥暴露给对方,在进行消息传递时,A经过B的公钥对数据加密,B接收到消息经过B的私钥进行解密,反之,B经过A的公钥进行加密,A接收到消息后经过A的私钥进行解密。
固然,这种方式可能存在数据传递被模拟的隐患,咱们能够经过数字签名等技术进行安全性的进一步提高。因为存在屡次的非对称加解密,这种方式带来的效率问题也更加严重。
DES算法在Java中的实现及运用:
// 用私钥对信息生成数字签名
public static String sign(byte[] data, String privateKey) throws Exception {
// 解密由base64编码的私钥
byte[] keyBytes = decryptBASE64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(priKey);
signature.update(data);
return encryptBASE64(signature.sign());
}
// 校验数字签名
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
// 解密由base64编码的公钥
byte[] keyBytes = decryptBASE64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance("MD5withRSA");
signature.initVerify(pubKey);
signature.update(data);
// 验证签名是否正常
return signature.verify(decryptBASE64(sign));
}
// 对私钥解密
public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
// 用公钥解密
public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
// 用公钥加密
public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
// 对公钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
// 用私钥加密
public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
// 取得私钥
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get("RSAPrivateKey");
return encryptBASE64(key.getEncoded());
}
// 取得公钥
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get("RSAPublicKey");
return encryptBASE64(key.getEncoded());
}
// 初始化密钥
public static Map<String, Object> initKey() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
// 公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
// 私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<String, Object>(2);
keyMap.put("RSAPublicKey", publicKey);
keyMap.put("RSAPrivateKey", privateKey);
return keyMap;
}
/**
* BASE64解密
*
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
}
/**
* BASE64加密
*
* @param key
* @return * @throws Exception */ public static String encryptBASE64(byte[] key) throws Exception { return (new BASE64Encoder()).encodeBuffer(key); }