DES加密
DES是一种对称加密(Data Encryption Standard)算法。
DES算法一般有两个关键点,第一个是加密算法,第二个是数据补位。

加密算法常见的有ECB模式和CBC模式:

ECB模式:电子密本方式,这是JAVA封装的DES算法的默认模式,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,则补足8个字节(注意:这里就涉及到数据补位了)进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

CBC模式:密文分组链接方式,这是.NET封装的DES算法的默认模式,它比较麻烦,加密步骤如下:
1、首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,就涉及到数据补位了)
2、第一组数据D1与向量I异或后的结果进行DES加密得到第一组密文C1(注意:这里有向量I的说法,ECB模式下没有使用向量I)
3、第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2
4、之后的数据以此类推,得到Cn
5、按顺序连为C1C2C3......Cn即为加密结果。

数据补位一般有NoPadding和PKCS7Padding(JAVA中是PKCS5Padding)填充方式,PKCS7Padding和PKCS5Padding实际只是协议不一样,根据相关资料说明:PKCS5Padding明确定义了加密块是8字节,PKCS7Padding加密快可以是1-255之间。但是封装的DES算法默认都是8字节,所以可以认为他们一样。数据补位实际是在数据不满8字节的倍数,才补充到8字节的倍数的填充过程。
NoPadding填充方式:算法本身不填充,比如.NET的padding提供了有None,Zeros方式,分别为不填充和填充0的方式。
PKCS7Padding(PKCS5Padding)填充方式:为.NET和JAVA的默认填充方式,对加密数据字节长度对8取余为r,如r大于0,则补8-r个字节,字节为8-r的值;如果r等于0,则补8个字节8。比如:
加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。

.NET中的DES加密
对于.NET,框架在System.Security.Cryptography命名空间下提供了DESCryptoServiceProvider作为System.Security.Cryptography.DES加密解密的包装接口,它提供了如下的4个方法:
public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
public override void GenerateIV()
public override void GenerateKey()
从.NET类库封装情况,加解密需要传入一个Key和IV向量。而且Key必须为8字节的数据,否则会直接抛异常出来,当使用ECB模式下,不管传入什么IV向量,加密结果都一样。

由于为ECB模式,因此IV这里设置什么值都是可以的,当为CBC模式下,则需要设置为其他值,比如:public static byte[] IV = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },才能正常加密解密。

JAVA中的DES加密
JAVA的javax.crypto.Cipher包下,提供了加密解密的功能,它的静态getInstance方法,可以返回一个Cipher对象,一般有public static final Cipher getInstance(String transformation)方法,transformation为:algorithm/mode/padding,分别表示算法名称,比如DES,也可以在后面包含算法模式和填充方式,但也可以只是算法名称,如为:"DES/CBC/PKCS5Padding","DES"等。JAVA中默认的算法为ECB,默认填充方式为PKCS5Padding。Cipher的Init方法用来初始化加密对象,常见的有:
public final void init(int opmode, Key key, AlgorithmParameterSpec params) ,
public final void init(int opmode,Key key, SecureRandom random),用SecureRandom时,一般用于不需要IV的算法模式,示例代码如下:
public static String encrypt2(String src) throws Exception {
SecureRandom sr = new SecureRandom();
DESKeySpec ks = new DESKeySpec(KEY.getBytes("UTF-8"));
SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");
SecretKey sk = skf.generateSecret(ks);
Cipher cip = Cipher.getInstance("DES/CBC/PKCS5Padding");//Cipher.getInstance("DES");
IvParameterSpec iv2 = new IvParameterSpec(IV);
cip.init(Cipher.ENCRYPT_MODE, sk, iv2);//IV的方式
//cip.init(Cipher.ENCRYPT_MODE, sk, sr);//没有传递IV
String dest = byteToHex(cip.doFinal(src.getBytes("UTF-8")));
return dest;

}

当默认用DES,JAVA会用ECB模式,因此这里IV向量没有作用,这里,但当用CBC模式下,如果还是用SecureRandom,则每次加密的结果都会不一样,因为JAVA内部会用随机的IV来初始化Cipher对象,如示例代码,由于Cipher.getInstance("DES/CBC/PKCS5Padding")使用了CBC,因此我这里用的javax.crypto.spec.IvParameterSpec包下的IvParameterSpec来初始化向量IV:
Private final static byte[] IV = new byte[] {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01};

总结
对于.NET和JAVA在使用DES对称加密时,需要大家指定一样的算法和填充模式,并且JAVA在写DES加解密算法时,还需要根据创建Cipher对象的不同,正确使用IV向量。在不同系统需要互相数据时,必须要明确的是加密算法,Key和算法模式,再根据不同模式是否需要IV向量,最后是填充模式。

kotlin实例:

0,base64编码

package com.wel.cryptimport java.io.UnsupportedEncodingException/*** Base64编码解码* Created by */
object Base64 {private val base64EncodeChars = charArrayOf('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/')private val base64DecodeChars = byteArrayOf(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1)fun encode(data: ByteArray): String {val sb = StringBuffer()val len = data.sizevar i = 0var b1: Intvar b2: Intvar b3: Intwhile (i < len) {b1 = ((data[i++]).toInt() and 0xff).toInt()if (i == len) {sb.append(base64EncodeChars[b1.ushr(2)])sb.append(base64EncodeChars[b1 and 0x3 shl 4])sb.append("==")break}b2 = (data[i++]).toInt() and 0xffif (i == len) {sb.append(base64EncodeChars[b1.ushr(2)])sb.append(base64EncodeChars[b1 and 0x03 shl 4 or (b2 and 0xf0).ushr(4)])sb.append(base64EncodeChars[b2 and 0x0f shl 2])sb.append("=")break}b3 = (data[i++]).toInt() and 0xffsb.append(base64EncodeChars[b1.ushr(2)])sb.append(base64EncodeChars[b1 and 0x03 shl 4 or (b2 and 0xf0).ushr(4)])sb.append(base64EncodeChars[b2 and 0x0f shl 2 or (b3 and 0xc0).ushr(6)])sb.append(base64EncodeChars[b3 and 0x3f])}return sb.toString()}@Throws(UnsupportedEncodingException::class)fun decode(str: String): ByteArray {val sb = StringBuffer()val data = str.toByteArray(charset("US-ASCII"))val len = data.sizevar i = 0var b1: Intvar b2: Intvar b3: Intvar b4: Intwhile (i < len) {/* b1 */do {b1 = base64DecodeChars[(data[i++]).toInt()].toInt()} while (i < len && b1 == -1)if (b1 == -1) break/* b2 */do {b2 = base64DecodeChars[(data[i++]).toInt()].toInt()} while (i < len && b2 == -1)if (b2 == -1) breaksb.append((b1 shl 2 or (b2 and 0x30).ushr(4)).toChar())/* b3 */do {b3 = data[i++].toInt()if (b3 == 61) return sb.toString().toByteArray(charset("ISO-8859-1"))b3 = base64DecodeChars[b3].toInt()} while (i < len && b3 == -1)if (b3 == -1) breaksb.append((b2 and 0x0f shl 4 or (b3 and 0x3c).ushr(2)).toChar())/* b4 */do {b4 = data[i++].toInt()if (b4 == 61) return sb.toString().toByteArray(charset("ISO-8859-1"))b4 = base64DecodeChars[b4].toInt()} while (i < len && b4 == -1)if (b4 == -1) breaksb.append((b3 and 0x03 shl 6 or b4).toChar())}return sb.toString().toByteArray(charset("ISO-8859-1"))}}

1,简单的DES加解密

package com.wel.crypt//import java.util.*
import com.wel.crypt.Base64
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.DESKeySpecobject DesCrypt{fun encrypt(input:String,password:String):String{//simple encryptval c = Cipher.getInstance("DES")//Cipher.getInstance("DES/CBC/PKCS5Padding")val keyfact=SecretKeyFactory.getInstance("DES")val keyn=DESKeySpec(password.toByteArray())val key= keyfact.generateSecret(keyn)c.init(Cipher.ENCRYPT_MODE,key)val encrypt=c.doFinal(input.toByteArray())return Base64.encode(encrypt)}fun decrypt(input:String,password:String):String{//simple encryptval c = Cipher.getInstance("DES")//Cipher.getInstance("DES/CBC/PKCS5Padding")val keyfact=SecretKeyFactory.getInstance("DES")val keyn=DESKeySpec(password.toByteArray())val key= keyfact.generateSecret(keyn)c.init(Cipher.DECRYPT_MODE,key)val encrypt=c.doFinal(Base64.decode(input))return String(encrypt)}}fun main(args:Array<String>){var s="我是我特打字了法克塞"var k="12341234"println("s size:${s.toByteArray().size}")
//    var encrypt=DesCrypt.encrypt(Base64.encode(s.toByteArray()),k)var encrypt=DesCrypt.encrypt(s,k)println("encrypt size:${encrypt.toByteArray().size}")
//    var bsen=Base64.encode(encrypt.toByteArray())
//    println("size:${bsen.toByteArray().size}")println("加密后:"+encrypt)var decrypt=DesCrypt.decrypt(encrypt,k)
//    var decrypt=DesCrypt.decrypt(encrypt.toByteArray(),k)
//    Base64.decode(decrypt)println("解密后:"+decrypt)
}

2,简单的AES加解密

package com.wel.cryptimport com.wel.crypt.Base64
import javax.crypto.Cipher
import javax.crypto.spec.SecretKeySpecobject AESCrypt{fun encode(input:String,password:String):String{val c=Cipher.getInstance("AES")val k=SecretKeySpec(password.toByteArray(),"AES")c.init(Cipher.ENCRYPT_MODE,k)val ens=c.doFinal(input.toByteArray())return Base64.encode(ens)}fun decode(input:String,password:String):String{val c=Cipher.getInstance("AES")val k=SecretKeySpec(password.toByteArray(),"AES")c.init(Cipher.DECRYPT_MODE,k)val des=c.doFinal(Base64.decode(input))return String(des)}
}fun main(args:Array<String>){val password="1234123412341234"var data="asd啊手动阀就是打开拉萨哥萨克的"val ens=AESCrypt.encode(data,password)println("encode:"+ens)val des=AESCrypt.decode(ens,password)println("encode:"+des)
}

3,RSA密钥产生,密钥存储,分段加密

package com.wel.cryptimport java.io.ByteArrayOutputStream
import java.security.KeyFactory
import java.security.KeyPairGenerator
import java.security.PrivateKey
import java.security.PublicKey
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.X509EncodedKeySpec
import javax.crypto.Cipherobject RSACrypt{//RSA一次性加密数据长度是117字节,超过就要分段//产生密钥,first是公钥,second是私钥fun generateKey(): Pair<PublicKey, PrivateKey> {val gkp=KeyPairGenerator.getInstance("RSA")val kp=gkp.generateKeyPair()return Pair(kp.public,kp.private)}//保存密钥对fun savePairOfKey(): Pair<PublicKey, PrivateKey> {val p=RSACrypt.generateKey()//产生密钥对,即公钥和私钥val fk=KeyFactory.getInstance("RSA")val privateKey =fk.generatePrivate(PKCS8EncodedKeySpec(p.second.encoded))val publicKey=fk.generatePublic(X509EncodedKeySpec(p.first.encoded))return Pair(publicKey,privateKey)}//RSA加密,公钥加密fun encodeByPublickKey(input:String,publicKey: PublicKey):String{val inputData=input.toByteArray()var offset=0var tmp:ByteArray=ByteArray(1024)var bos=ByteArrayOutputStream()val c=Cipher.getInstance("RSA")c.init(Cipher.ENCRYPT_MODE,publicKey)while(inputData.size-offset>0){if(inputData.size-offset>=117) {tmp = c.doFinal(inputData, offset, 117)offset +=117}else{tmp = c.doFinal(inputData, offset, inputData.size-offset)offset =inputData.size}bos.write(tmp)}bos.close()return Base64.encode(bos.toByteArray())}//RSA解密,私钥解密fun decodeByPrivateKey(input:String,privateKey: PrivateKey):String{val inputData=Base64.decode(input)//input.toByteArray()var offset=0var tmp:ByteArray=ByteArray(1024)var bos=ByteArrayOutputStream()val c=Cipher.getInstance("RSA")c.init(Cipher.DECRYPT_MODE,privateKey)while(inputData.size-offset>0){if(inputData.size-offset>=128) {tmp = c.doFinal(inputData, offset, 128)offset +=128}else{tmp = c.doFinal(inputData, offset, inputData.size-offset)offset =inputData.size}bos.write(tmp)}bos.close()return bos.toString()}
//    fun decodeByPrivateKey(input:String,privateKey: PrivateKey):String{
//        val c=Cipher.getInstance("RSA")
//        c.init(Cipher.DECRYPT_MODE,privateKey)
//        val enr=c.doFinal(Base64.decode(input))
//        return String(enr)
//    }//RSA加密,私钥加密fun encodeByPrivateKey(input:String,privateKey: PrivateKey):String{val inputData=input.toByteArray()var offset=0var tmp:ByteArray=ByteArray(1024)var bos=ByteArrayOutputStream()val c=Cipher.getInstance("RSA")c.init(Cipher.ENCRYPT_MODE,privateKey)while(inputData.size-offset>0){if(inputData.size-offset>=117) {tmp = c.doFinal(inputData, offset, 117)offset +=117}else{tmp = c.doFinal(inputData, offset, inputData.size-offset)offset =inputData.size}bos.write(tmp)}bos.close()return Base64.encode(bos.toByteArray())}//RSA解密,公钥解密fun decodeByPublickKey(input:String,publicKey: PublicKey):String{val inputData=Base64.decode(input)//input.toByteArray()var offset=0var tmp:ByteArray=ByteArray(1024)var bos=ByteArrayOutputStream()val c=Cipher.getInstance("RSA")c.init(Cipher.DECRYPT_MODE,publicKey)while(inputData.size-offset>0){if(inputData.size-offset>=128) {tmp = c.doFinal(inputData, offset, 128)offset +=128}else{tmp = c.doFinal(inputData, offset, inputData.size-offset)offset =inputData.size}bos.write(tmp)}bos.close()return bos.toString()}}fun main(args:Array<String>){val data="sdjlkjkl顺利打开解放螺丝钉解放,wo我饿哦问哦额我iew哦iwewerwqheuieh  维护iewowieh 哦为" +"人很好iweowieh 修车师傅士大夫阿道夫温柔温柔似的发射点发生答复是德国法国东方发规定士大夫是的方法士大夫士大夫"
//    val p=RSACrypt.generateKey()//产生密钥对,即公钥和私钥
//    println("publickkey :"+Base64.encode(p.first.encoded))
//    println("privatekey :"+Base64.encode(p.second.encoded))val p=RSACrypt.savePairOfKey()//公钥加密,私钥解密
//    val pubens=RSACrypt.encodeByPublickKey(data,p.first)//pulickey encode
//    println("publickkey encode:"+pubens)
//    val privdes=RSACrypt.decodeByPrivateKey(pubens,p.second)
//    println("privatekey decode:"+privdes)//私钥加密,公钥解密val pubens=RSACrypt.encodeByPrivateKey(data,p.second)//pulickey encodeprintln("publickkey encode:"+pubens)val privdes=RSACrypt.decodeByPublickKey(pubens,p.first)println("privatekey decode:"+privdes)}

kotlin写的加解密算法,包括模式和填充方式相关推荐

  1. Cryptography,一个C#写的加解密算法的类

    一个加解密算法的类,如下: Code using System; using System.IO; using System.Security.Cryptography; using System.T ...

  2. 微信支付AES加解密算法

    微信支付AES加解密算法 AES256/ECB/PKCS7Padding 一.AES 高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法 二. ...

  3. .Net/C# 实现: FlashFXP 地址簿中站点密码的加解密算法

    参阅 CCFer & TLFer : kanbol 的 Java 代码翻译修改而成: kanbol 说: 之前在TLF写过一个程序自动更新flashfxp的地址簿,也就是修改sites.dat ...

  4. AES加解密算法详解

    0 AES简介 美国国家标准技术研究所在2001年发布了高级加密标准(AES).AES是一个对称分组密码算法,旨在取代DES成为广泛使用的标准. 根据使用的密码长度,AES最常见的有3种方案,用以适应 ...

  5. Android金融支付常见加解密算法及安全防护

    引言 因为本人从事的金融 IC 卡和移动支付相关的开发工作,在日常研发过程中,对 APP 信息安全防护方面尤为重视,所以现总结下金融支付相关的加解密算法以及常见的安全防范措施. Android 端常见 ...

  6. 安全系列(二)-银行加密体系与加解密算法速览

    一.银行3级加密体系说明: 转:加密体系介绍(LMK.ZMK.ZAK.ZPK)_炎升的博客-CSDN博客_lmk密钥 二.加解密算法 1.分类说明 其中按国际和国内使用主要分为:通用算法和国密. 通用 ...

  7. (转)base64编码(严格说来,base64不算作加解密算法)

    [README] 1.本文转自: Java base64加密解密 - xuwc - 博客园参考: https://www.cnblogs.com/luguo3000/p/3940197.html ht ...

  8. Python中的AES加解密算法

    AES加密的参数及其条件:这个AES加密的主要坑就在于这些条件,首先AES加密有几个参数 秘钥:加密的时候用秘钥,解密的时候需要同样的秘钥才能解出来 明文:需要加密的内容 模式:aes 加密常用的有E ...

  9. python中凯撒密码_python实现凯撒密码、凯撒加解密算法

    凯撒密码的原理:计算并输出偏移量为3的凯撒密码的结果 注意:密文是大写字母,在变换加密之前把明文字母都替换为大写字母 def casar(message): # *************begin* ...

最新文章

  1. 批量梯度下降(BGD)、随机梯度下降(SGD)以及小批量梯度下降(MBGD)的理解
  2. Android内核开发必备知识
  3. 多重背包单调队列优化思路_多重背包之单调队列优化理论性总结
  4. Apache日志配置
  5. 关于MySQL 查询表数据大小的总结
  6. 解决eclipse 文件更新不自动刷新的问题
  7. azure 入门_Azure Data Studio(ADS)入门; 初始安装和配置
  8. 从0开始的Python学习006流程控制
  9. 使用select和show命令查看mysql数据库系统信息
  10. HFS 2.3x 远程命令执行(抓鸡黑客末日)
  11. Win11 蓝牙功能消失
  12. wifi和wlan有什么区别
  13. 安利一款提醒休息的工具--重度电脑工作者和程序员必备
  14. MoviePy中文乱码的原因以及解决办法
  15. 建筑八大员培训湖北劳务员培训施工现场劳务人员多元化管理
  16. 公开课教学反思 计算机,《百数表》公开课教学反思
  17. ACC自适应巡航和定速巡航的区别
  18. 请java老鸟指教一下
  19. pcap_findalldevs_ex 文件没有定义
  20. 任正非蜕变,华为新生

热门文章

  1. 《How to be nubility for coder》
  2. 虎牙被抬员工当事人已收到开庭通知
  3. 【恩墨学院】原来银行都在用这些数据库
  4. 【Dlib人脸识别】1. Dlib人脸检测的基本原理
  5. 【算法】【递归与动态规划模块】两个字符串的最长公共子数组
  6. Flash常用源代码大全
  7. 几次推广都没能火起来,腾讯直接把微视嵌入朋友圈了?
  8. javaserver_JavaServer页面简介
  9. 看完这篇,你就会知道 Lineage OS 系统的一切
  10. 使用div制作表格效果