发送方和接收方 用同一个秘钥对数据加密解密
例:
A和B约定好秘钥"123456"
(比如客户端和服务端)
A给B发消息:"我喜欢你"
A用 "123456"
对 “我喜欢你” 加密得到结果 “乱码”,把 “乱码” 发给B
B用 "123456"
对 “乱码” 解密得到结果 "我喜欢你"
对称加密的代表算法有DES,AES等,这里只看DES,AES
DES:
数据加密算法(Data Encryption Algorithm,缩写DEA):
运算速度快,资源消耗较少,安全性低
AES:
高级加密标准(英语:Advanced Encryption Standard,缩写AES):
这个标准用来替代原先的DES,运算速度快,安全性高,资源消耗少
代码示例:
package com.i.cipher
import android.util.Base64
import java.security.*
import javax.crypto.Cipher
import javax.crypto.KeyGenerator
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.DESKeySpec
import javax.crypto.spec.SecretKeySpec
//---------------------------------DES-----------------------------------
fun desEnc(input: String, password: String): String {
val cipher = Cipher.getInstance("DES")
val secretKey = SecretKeyFactory.getInstance("DES")
val keySpec = DESKeySpec(password.toByteArray())
val key: Key = secretKey.generateSecret(keySpec)
cipher.init(Cipher.ENCRYPT_MODE, key)
val encrypt = cipher.doFinal(input.toByteArray())
return Base64.encodeToString(encrypt, Base64.NO_WRAP)
}
fun desDec(input: String, password: String): String {
val cipher = Cipher.getInstance("DES")
val secretKey = SecretKeyFactory.getInstance("DES")
val keySpec = DESKeySpec(password.toByteArray())
val key: Key = secretKey.generateSecret(keySpec)
cipher.init(Cipher.DECRYPT_MODE, key)
val encrypt = cipher.doFinal(Base64.decode(input, Base64.NO_WRAP))
return String(encrypt)
}
//---------------------------------AES-----------------------------------
fun aesEnc(input: String, password: String): String {
val cipher = Cipher.getInstance("AES")
val keySpec = SecretKeySpec(password.toByteArray(), "AES")
cipher.init(Cipher.ENCRYPT_MODE, keySpec)
val encrypt = cipher.doFinal(input.toByteArray())
return Base64.encodeToString(encrypt, Base64.NO_WRAP)
}
fun aesDec(input: String, password: String): String {
val cipher = Cipher.getInstance("AES")
val keySpec = SecretKeySpec(password.toByteArray(), "AES")
cipher.init(Cipher.DECRYPT_MODE, keySpec)
val encrypt = cipher.doFinal(Base64.decode(input, Base64.NO_WRAP))
return String(encrypt)
}
//---------------------------------AES(keyGenerator)推荐-----------------------------------
fun createKey(password: String): Key {
val keyGenerator = KeyGenerator.getInstance("AES")
keyGenerator.init(128, SecureRandom(password.toByteArray()))
return keyGenerator.generateKey()
}
fun encode(key: Key, input: String): String {
val cipher = Cipher.getInstance("AES")
cipher.init(Cipher.ENCRYPT_MODE, key)
val dataByte = cipher.doFinal(input.toByteArray())
val encodeByte = Base64.encodeToString(dataByte, Base64.NO_WRAP)
return encodeByte
}
fun decode(key: Key, input: String): String {
val decodeByte = Base64.decode(input.toByteArray(), Base64.NO_WRAP)
val cipher = Cipher.getInstance("AES")
cipher.init(Cipher.DECRYPT_MODE, key)
val dataByte = cipher.doFinal(decodeByte)
return String(dataByte)
}
测试代码
//base64的基本加解密
btn_base64.setOnClickListener {
val input = "今天天气啦啦啦"
tv_before.setText("加密前:" + input)
val encode = Base64.encodeToString(input.toByteArray(), Base64.NO_WRAP);
tv_after.setText("加密后:" + encode)
val decode = String(Base64.decode(encode, Base64.NO_WRAP))
tv_dec_after.setText("解密后:" + decode)
}
btn_des.setOnClickListener {
val input = "今天天气不错"
//8位密码
val password = "12345678"
tv_before.setText("加密前:" + input)
val encrypt = desEnc(input, password)
tv_after.setText("加密后:" + encrypt)
val decrypt = desDec(encrypt, password)
tv_dec_after.setText("解密后:" + decrypt)
}
btn_aes.setOnClickListener {
val input = "今天天气还行"
//16位密码
val password = "1234567812345678"
tv_before.setText("加密前:" + input)
val encrypt = aesEnc(input, password)
tv_after.setText("加密后:" + encrypt)
val decrypt = aesDec(encrypt, password)
tv_dec_after.setText("解密后:" + decrypt)
}
btn_aes_keyGenerator.setOnClickListener {
val input = "今天天气太好了"
val password = "123456abc"
tv_before.setText("加密前:" + input)
val createKey = createKey(password)
val encode = encode(createKey, input)
tv_after.setText("加密后:" + encode)
val decode = decode(createKey, encode)
tv_dec_after.setText("解密后:" + decode)
}
发送方用接收方的公钥加密,接收方用自己的私钥解密
例:
A生成"APrikey","APubkey"
B生成"BPrikey","BPubkey"
A给B发消息:"我喜欢你"
A用 "BPubkey"
对 “我喜欢你” 加密得到结果 “乱码”,把 “乱码” 发给B
B用 "BPrikey"
对 “乱码” 解密得到结果 "我喜欢你"
B给A发消息同理
//---------------------------------RSA-----------------------------------
fun createKeyPair(): KeyPair {
val generator = KeyPairGenerator.getInstance("RSA")
return generator.genKeyPair()
}
/**
* 私钥加密
*/
fun encByPrivateKey(input: String, privateKey: PrivateKey): String {
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, privateKey)
val encrypt = cipher.doFinal(input.toByteArray())
return Base64.encodeToString(encrypt, Base64.NO_WRAP)
}
/**
* 公钥解密
*/
fun decByPublicKey(input: String, publicKey: PublicKey): String {
val decode = Base64.decode(input, Base64.NO_WRAP)
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, publicKey)
val encrypt = cipher.doFinal(decode)
return String(encrypt)
}
/**
* 公钥加密
*/
fun encByPublicKey(input: String, publicKey: PublicKey): String {
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, publicKey)
val encrypt = cipher.doFinal(input.toByteArray())
return Base64.encodeToString(encrypt, Base64.NO_WRAP)
}
/**
* 私钥解密
*/
fun decByPrivateKey(input: String, privateKey: PrivateKey): String {
val decode = Base64.decode(input, Base64.NO_WRAP)
val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, privateKey)
val encrypt = cipher.doFinal(decode)
return String(encrypt)
}
测试代码
//私钥加密,公钥解密
fun priTopub() {
val input = "今天天气真好啊"
tv_before.setText("加密前:" + input)
val keyPair = createKeyPair()
val encByPrivateKey = encByPrivateKey(input, keyPair.private)
tv_after.setText("加密后:" + encByPrivateKey)
val decByPublicKey = decByPublicKey(encByPrivateKey, keyPair.public)
tv_dec_after.setText("解密后:" + decByPublicKey)
}
//公钥加密,私钥解密
fun pubTopri() {
val input = "今天天气非常好啊"
tv_before.setText("加密前:" + input)
val keyPair = createKeyPair()
val encByPublicKey = encByPublicKey(input, keyPair.public)
tv_after.setText("加密后:" + encByPublicKey)
val decByPrivateKey = decByPrivateKey(encByPublicKey, keyPair.private)
tv_dec_after.setText("解密后:" + decByPrivateKey)
}
参考:
https://zhuanlan.zhihu.com/p/49494990
https://blog.csdn.net/u011109931/article/details/79466587
https://blog.csdn.net/hongxue8888/article/details/103850353
源码:https://gitee.com/zzgits/Cipher
百度百科:https://baike.baidu.com/item/%E9%9D%9E%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/1208652?fr=aladdin
1.A要向B发送信息,A和B都要产生一对用于加密和解密的公钥和私钥。
2.A的私钥保密,A的公钥告诉B;B的私钥保密,B的公钥告诉A。
3.A要给B发送信息时,A用B的公钥加密信息,因为A知道B的公钥。
4.A将这个消息发给B(已经用B的公钥加密消息)。
5.B收到这个消息后,B用自己的私钥解密A的消息。其他所有收到这个报文的人都无法解密,因为只有B才有B的私钥。
拓展:
HTTPS原理
对称加密速度快,不安全
非对称安全,传输数据小
那怎么办呢?怎么做到又安全,传输的数据又多呢?
答案:用对称加密传输数据,用非对称加密只加密对称加密生成的秘钥(秘钥数据小)
保证了对称加密的秘钥的安全了,那么传输数据自然就安全了。
客户端服务端交互 场景:
客户端: 我要发起HTTPS请求,麻烦给我一个非对称加密的公钥;
服务器: (生成一对非对称加密的密钥对,然后把公钥发给客户端),接着,这是公钥;
客户端:收到公钥并用公钥对对称秘钥加密
服务器:收到对称秘钥后,用自己的私钥解密
现在,客户端和服务器都知道了这把密钥,就能愉快地用这个密钥对称加密数据…
此时有一个坏人:
坏人: 在客户端向服务器申请公钥的时候,劫持服务器返回的A公钥,然后自己生成一个新的公钥返回给客户端。
客户端:收到公钥并用公钥对对称秘钥加密
坏人:直接就拿到了对称秘钥
为了骗服务端,坏人又使用A公钥加密发给服务器。
这里是说客户端收到了假公钥,那如果客户端那边把公钥写死在代码里面,这个问题是否就不存在了呢?
答案:否,坏人可以通过其他方式拿到A公钥,然后自己生成一个新的对称秘钥返回给服务端。
服务端以为这个新的对称秘钥就是客户端给他的。
原文请看:https://www.jianshu.com/p/ca7df01a9041