系列文章目录

(一)Kotlin加密/解密之ASCII码

(二)Kotlin加密/解密之凯撒加密算法

(三)Kotlin加密/解密之AES和DES


文章目录

  • 系列文章目录
  • 前言
  • 一、RSA算法的加解密流程和改进
    • 1.RSA算法的加解密流程
    • 2.RSA加解密的缺点以及改进
  • 二、数字签名
    • 1.消息摘要
      • 1.MD5
      • 2. sha1
      • 3.sha265
    • 2.数字签名
  • 3.Kotlin 中RSA的加解密实现
    • 1.RSA算法的使用注意点
    • 2.RSA算法的实现
      • (1)获取公钥和私钥
      • (2)设置算法以及分段加密解密的最大长度
      • (3)私钥加密
      • (4)公钥加密
      • (5)私钥解密
      • (6)公钥解密
  • 总结

前言

在前面的章节中我们说到了加密分为对称加密和非对称加密,对称加密咱们前面已经讲完了,本节要讲的是非对称加密RSA,我们都知道,对称加密的加密和解密的密钥是相同的,这就导致了只要破解得到密钥,那么密文就和原文没啥区别了,而本节要学的RSA算法,是使用公钥和私钥来进行加解密,大大提高了密文的破解难度,接下来就让我们看看在Kotlin中如何实现RSA算法的加解密吧。


一、RSA算法的加解密流程和改进

1.RSA算法的加解密流程

在RSA算法中,通信的双方用户A和用户B各自通过RSA算法生成密钥对,这个密钥对分为公钥和私钥,使用公钥加密的密文,只能使用对应的私钥进行解码,反之使用私钥加密的密文,只能使用对应的公钥匙进行解密。所以RSA的加密流程就是:
总结起来分为以下两步:
(1)用户A和用户B交换公钥,这个公钥是公开的,所有人都知道也没关系。
(2)当想和对方通信时,就使用对方的公钥加密数据,对方收到加密的信息后,使用自己的私钥解密,比如用户A想给用户B发送消息,用户A可以使用用户B的公钥加密信息,用户B收到信息后使用自己的私钥进行解密就可以了,反之亦然。

2.RSA加解密的缺点以及改进

这时读者可能会觉得上面的加解密方案很好了吧,其实不然,因为RSA的加解密有个缺点就是加解密速度慢,这会导致本来只想发一句“我爱你”,等对方收到的消息的时候可能已成为别人的新娘。对于这个问题,咱们可以结合对称加密和非对称加密的优点。我们都知道,对称加密算法速度快,但是不够安全,而RSA算法够安全,但是不够快,所以我们就可以整合他们的优点。

具体方案很简单,就是使用RSA算法将对称加密的密钥传给对方。后面的通信都使用对称加密算法对传输的信息进行加解密,因为我们最怕的就是加解密的密钥被黑客截获,所以我们使用安全性较高的RSA加密传输咱们后面通信中会使用的对称加密的密钥。这样就达到了既保证了安全,又保证了速度。

二、数字签名

看到这里我们大家是不是会以为咱们的通信已经很安全了,其实不是,咱们在通信前需要和通信的对象交换公钥,这时就会出现一个问题,你如何确定和你交换公钥的人就是你想通信的对象呢?

比如A想和B通信,在和B交换公钥的时候,被黑客截获,这时候黑客就会伪装成A把自己的公钥传给B,B毫不知情,以为黑客是A,就将自己的隐私啥的都告诉了黑客。这时将是大型的社死现场,或者是电信诈骗现场。为了解决这个问题,数字证书就出现了。

1.消息摘要

在说解决方法之前,我们先了解一个知识,那就是消息摘要。消息摘要就是对一份数据,进行一个单向的 Hash 函数,生成一个固定长度的 Hash 值,这个值就是这份数据的摘要,也称为指纹。简单理解就是一个单向加密的过程,加密以后不可逆,无法破解。常用的算法有:MD5,sha1, sha265。消息摘要可以用于对用户密码加密保存,对软件下载站使用消息摘要计算文件指纹,防止被篡改,然后就是咱们后面要讲的数字签名了。在kotlin中可以使用下面的代码生成消息摘要:

1.MD5

fun Md5(input:String):String{val digest = MessageDigest.getInstance("MD5")val result = digest.digest(input.toByteArray())println("md5 encrypt size: ${result.size}")//加密前16个字节,加密后转成16进制32字节,结果是固定长度,无仑数据多大//转成16进制return toHex(result)}

转16进制的方法:

    fun toHex(byteArray: ByteArray):String{//转成16进制val sb = StringBuilder()val result =  with(StringBuilder()){byteArray.forEach {//println(it)//打印每一个元素val value = itval hex = value.toInt() and (0xFF)val hexStr = Integer.toHexString(hex)// println(hexStr)if(hexStr.length == 1){append("0").append(hexStr)}else{append(hexStr)}}this.toString()}return result}

2. sha1

 fun sha1(input: String):String{val digest=MessageDigest.getInstance("SHA-1")val result =  digest.digest(input.toByteArray())println("sha1 加密后: ${result.size}")//转成16进制val toHex = toHex(result)println("sha1 转成16进制:${toHex.toByteArray().size}" )return toHex}

3.sha265

 fun sha256(input: String):String{val digest=MessageDigest.getInstance("SHA-256")val result =  digest.digest(input.toByteArray())println("sha256 加密后: ${result.size}")//转成16进制val toHex = toHex(result)println("sha256 转成16进制:${toHex.toByteArray().size}" )return toHex}

2.数字签名

用户A想和B通信,A在给B发送公钥的过程中,会把公钥和自己的信息通过Hash算法(md5/sha1/sha265)生成消息摘要,为了防止消息摘要被调换,A会通过CA(数字证书签发机构)题哦那个的私钥对消息摘要进行加密来形成数字证书,当B拿到数字证书后,会用CA提供的公钥对数字证书里面的数字签名解密得到消息摘要,然后对数字证书里面的A的公钥和A的个人信息进行Hash得到另一份消息摘要,然后把两份消息摘要进行对比,如果相同,则证明这些信息的确是A传送过来的,否则不是。流程图如下:
这里面涉及到一个签名和认证的过程,在kotlin中代码如下:

签名:

 fun sign(input:String,privateKey: PrivateKey):String{//获取数字签名实例对象val signature = Signature.getInstance("SHA256withRSA")//初始化签名signature.initSign(privateKey)//设置数据源signature.update(input.toByteArray())//签名val sign = signature.sign()return Base64.encode(sign)}

认证:

 fun verify(input: String, publicKey: PublicKey,sign:String): Boolean {//校验val signature = Signature.getInstance("SHA256withRSA")//初始化签名signature.initVerify(publicKey)//传入数据源signature.update(input.toByteArray())//校验签名信息return signature.verify(Base64.decode(sign))}

3.Kotlin 中RSA的加解密实现

1.RSA算法的使用注意点

上面说了那么多,我们还需要知道如何在kotlin中使用RSA算法。
(1)首先我们需要知道RSA加密的公钥和私钥非常长,看一张图:
这张图中,最开始的两行就是公钥和私钥特别的长,这也解释了为啥RSA算法加密慢的问题。

(2)第二个问题我们需要注意,加密的内容长度会受限制,啥意思呢,就是使用RSA算法加密的内容长度不能太长,否则会加密失败:如下图
那么咱们要想加密更长的数据就没办法了吗?当然不是,我们可以分段加密,即将要加密的内容分成一段一段的加密,解密的时候再分段解密就可以了。

(3)我们要注意公钥加密的,要用对应私钥进行解密,反之一样,直接看代码吧。

2.RSA算法的实现

(1)获取公钥和私钥

 val generator = KeyPairGenerator.getInstance("RSA") //密钥生成器val keyPair = generator.genKeyPair()val publicKey = keyPair.publicval privateKey = keyPair.privateprintln("public key: ${Base64.encode(publicKey.encoded)}")println("privateKey key: ${Base64.encode(privateKey.encoded)}")

(2)设置算法以及分段加密解密的最大长度

    val transformation = "RSA"val ENCRYPT_MAX_SIZE = 245//最大加密长度,有的是177,看具体的支持长度val DECRYPT_MAX_SIZE = 256//最大加密长度,有的是177,看具体的支持长度

(3)私钥加密

 fun encryptByPrivateKey(input:String,privateKey:PrivateKey):String{val byteArray = input.toByteArray();//1.创建cipher对象val cipher = Cipher.getInstance(transformation)//2。初始化ciphercipher.init(Cipher.ENCRYPT_MODE, privateKey)//3.加密解密var temp:ByteArray? = nullvar offset = 0 //当前偏移的位置val bos = ByteArrayOutputStream()while (byteArray.size - offset >0){//没有加密完//每次最大加密245字节if((byteArray.size - offset) >= ENCRYPT_MAX_SIZE){//剩余部分大于245//加密完整245字节temp = cipher.doFinal(byteArray,offset, ENCRYPT_MAX_SIZE)//重新计算偏移的位置offset += ENCRYPT_MAX_SIZE}else{//加密的最后一块temp = cipher.doFinal(byteArray,offset, byteArray.size - offset)offset = byteArray.size}//存储到临时缓冲区temp?.let { bos.write(it) }}bos.close()return Base64.encode(bos.toByteArray())}

(4)公钥加密

    fun encryptByPublicKey(input:String,publicKey:PublicKey):String{//分段加密val byteArray = input.toByteArray();//1.创建cipher对象val cipher = Cipher.getInstance(transformation)//2。初始化ciphercipher.init(Cipher.ENCRYPT_MODE, publicKey)//3.加密解密var temp:ByteArray? = nullvar offset = 0 //当前偏移的位置val bos = ByteArrayOutputStream()while (byteArray.size - offset >0){//没有加密完//每次最大加密245字节if((byteArray.size - offset) >= ENCRYPT_MAX_SIZE){//剩余部分大于245//加密完整245字节temp = cipher.doFinal(byteArray,offset, ENCRYPT_MAX_SIZE)//重新计算偏移的位置offset += ENCRYPT_MAX_SIZE}else{//加密的最后一块temp = cipher.doFinal(byteArray,offset, byteArray.size - offset)offset = byteArray.size}//存储到临时缓冲区temp?.let { bos.write(it) }}bos.close()return Base64.encode(bos.toByteArray())}

(5)私钥解密

fun decryptByPrivateKey(input:String,privateKey:PrivateKey):String{val byteArray = Base64.decode(input)//1.创建cipher对象val cipher = Cipher.getInstance(transformation)//2。初始化ciphercipher.init(Cipher.DECRYPT_MODE, privateKey)//3.分段解密var temp:ByteArray? = nullvar offset = 0 //当前偏移的位置val bos = ByteArrayOutputStream()while (byteArray.size - offset >0){//没有加密完//每次最大加密245字节if((byteArray.size - offset) >= DECRYPT_MAX_SIZE){//剩余部分大于245//加密完整245字节temp = cipher.doFinal(byteArray,offset, DECRYPT_MAX_SIZE)//重新计算偏移的位置offset += DECRYPT_MAX_SIZE}else{//加密的最后一块temp = cipher.doFinal(byteArray,offset, byteArray.size - offset)offset = byteArray.size}//存储到临时缓冲区temp?.let { bos.write(it) }}bos.close()return String(bos.toByteArray())}

(6)公钥解密

 fun decryptByPublicKey(input:String,publicKey: PublicKey):String{val byteArray = Base64.decode(input)//1.创建cipher对象val cipher = Cipher.getInstance(transformation)//2。初始化ciphercipher.init(Cipher.DECRYPT_MODE, publicKey)//3.分段解密var temp:ByteArray? = nullvar offset = 0 //当前偏移的位置val bos = ByteArrayOutputStream()while (byteArray.size - offset >0){//没有加密完//每次最大加密245字节if((byteArray.size - offset) >= DECRYPT_MAX_SIZE){//剩余部分大于245//加密完整245字节temp = cipher.doFinal(byteArray,offset, DECRYPT_MAX_SIZE)//重新计算偏移的位置offset += DECRYPT_MAX_SIZE}else{//加密的最后一块temp = cipher.doFinal(byteArray,offset, byteArray.size - offset)offset = byteArray.size}//存储到临时缓冲区temp?.let { bos.write(it) }}bos.close()return String(bos.toByteArray())}

总结

以上就是今天要讲的内容,至此,kotlin加解密的文章就到此结束了,相信读者已经了解了对数据的加密和解密以及各种加密算法的特点,希望这系列文章能帮助你在工作中发挥作用。感谢阅读。青山不改,绿水长流,后会有期~~~

(四)Kotlin加密/解密之RSA算法和数字签名相关推荐

  1. 第十九篇:JAVA加密解密之RSA算法

    RSA算法简介 RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年首 ...

  2. (三)Kotlin加密/解密之AES和DES

    Kotlin加密/解密系列 (一)Kotlin加密/解密之ASCII码 (二)Kotlin加密/解密之凯撒加密算法 文章目录 Kotlin加密/解密系列 前言 一.加密算法 二.Base64编码 1. ...

  3. php算法入门,a011.PHP实战:加密解密,简单算法入门

    原标题:a011.PHP实战:加密解密,简单算法入门 在PHP编程中,很多时候我们会遇到传递信息的问题,而传递过程中为了安全,我们肯定是要进行加密和解密的,这里,我们来说一说使用PHP怎么进行加密解密 ...

  4. java处理加密文件---实现RSA算法

    1  RSA算法的原理如下: 1.1原理      假设我们需要将信息从机器A传到机器B,首先由机器B随机确定一个Key,我们称之为密匙private_key,将这个可KEY始终保存在机器B中而不发出 ...

  5. java android rsa加密解密_Android RSA加密解密

    转载 http://blog.csdn.net/bbld_/article/details/38777491 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十 ...

  6. ios php rsa加密解密,php rsa加密解密使用详解

    第一条命令生成原始 RSA私钥文件 rsa_private_key.pem,第二条命令将原始 RSA私钥转换为 pkcs8格式,第三条生成RSA公钥 rsa_public_key.pem 从上面看出通 ...

  7. 加密 解密常用的算法

    base64 字符串的重新编码,一般会导致编码后变长 gzip压缩 DES加密解密,对称的加密的算法 DES是一种对称的加密方式,因为用的同一个密钥. MD5是不可逆的,一般用来密文传输,比如传输的 ...

  8. PHP 自己研究的一套 加密 解密 字符串的算法

    <?phpextension_loaded('openssl') or die('php需要openssl扩展支持');$sy = "-----BEGIN PRIVATE KEY--- ...

  9. 使用Crypto实现RSA算法的数字签名和检验

    总的来说,需要用到的对象有三个: Crypto.PublicKey.RSA:用来生成RSA算法的密钥对象 Crypto.Hash.SHA384:用来获取信息的摘要对象 Crypto.Signature ...

  10. java android rsa加密解密_Android RSA数据加密与Java服务端RSA私钥解密出错问题

    1. 出错描述:服务RSA解密抛出javax.crypto.BadPaddingException: Decryption error 2.出错原因:Android系统使用的虚拟机(dalvik)跟S ...

最新文章

  1. 精度45.9%,推理速度72.9FPS,百度飞桨推出工业级目标检测模型 PP-YOLO
  2. js鼠标略过自动选择当前行
  3. python中mid_使用Python进行新浪微博的mid和url互相转换实例(10进制和62进制互算)...
  4. 红帽虚拟化RHEV-安装RHEV-M
  5. MongoDB(课时18 修改器)
  6. ASP.NET 定时执行任务(定时器)
  7. Vue全家桶实战01_【从入门到放弃系列】
  8. oracle 数据库,用户管理以及表空间等相关基础操作
  9. LeetCode 1500. Design a File Sharing System(哈希map+优先队列)
  10. java jvm目录,JVM(Java虚拟机)中过程工作目录讲解
  11. 实战 | 后端日志的前世今生
  12. 8086寄存器的配合使用
  13. java 二分查找_Java二分法查找
  14. python创建字符串_Python基础之字符串
  15. Grails集成Quartz插件实现定时任务(Job)
  16. 操作系统进程调度算法(c语言实现)
  17. EQ频响曲线绘制和DRC特性曲线绘制
  18. 打砖块python游戏源代码_python制作一个打砖块小游戏
  19. latex 算法,算法包 algorithm, algorithm2e
  20. USACO/ratios 3.2.4

热门文章

  1. 安装drupal9报错
  2. 期权、期货及其他衍生产品 第二章 课程笔记整理
  3. 干货分享:常见的十种破解密码方法!赶紧收藏!
  4. TP Link 路由器 设置
  5. Tplink路由器配置页面IP地址_tplogin.cn页面IP地址_TpLink易展版LAN口地址获取_如何获得tplogin.cn的IP地址_获取易展版TPLinkWIFI6路由器的配置地址方法
  6. comsol操作技巧
  7. 4种JavaScript中获取HTML元素的方式
  8. 做了一个iGoogle新闻Gardget
  9. 【Oracle】批量造测试数据
  10. 小鑫の日常系列故事(一)——判断对错 (sdut oj)