您的位置:首页 > 其它

scala语言实现各种加密算法

2018-07-09 12:02 417 查看

因子

 

  现在一些接口交互的时候回用到各种加密算法,现在总结一下我遇到的几个算法。

1. MD5加密

MD5消息摘要算法,属Hash算法一类。MD5算法对输入任意长度的消息进行运行,产生一个128位的消息摘要。

以下所描述的消息长度、填充数据都以位(Bit)为单位,字节序为小端字节。

算法原理

1、数据填充

对消息进行数据填充,使消息的长度对512取模得448,设消息长度为X,即满足X mod 512=448。根据此公式得出需要填充的数据长度。

填充方法:在消息后面进行填充,填充第一位为1,其余为0。

2、添加消息长度

在第一步结果之后再填充上原消息的长度,可用来进行的存储长度为64位。如果消息长度大于264,则只使用其低64位的值,即(消息长度 对 264取模)。

在此步骤进行完毕后,最终消息长度就是512的整数倍。

3、数据处理

准备需要用到的数据:

  • 4个常数: A = 0x67452301, B = 0x0EFCDAB89, C = 0x98BADCFE, D = 0x10325476;
  • 4个函数:F(X,Y,Z)=(X & Y) | ((~X) & Z); G(X,Y,Z)=(X & Z) | (Y & (~Z));  H(X,Y,Z)=X ^ Y ^ Z; I(X,Y,Z)=Y ^ (X | (~Z));

把消息分以512位为一分组进行处理,每一个分组进行4轮变换,以上面所说4个常数为起始变量进行计算,重新输出4个变量,以这4个变量再进行下一分组的运算,如果已经是最后一个分组,则这4个变量为最后的结果,即MD5值。

具体计算的实现较为复杂,建议查阅相关书籍,下面给出在C++上的实现代码。

转自:点击打开链接

代码如下:

[code]val digest = MessageDigest.getInstance("MD5")
val text = "需要加密的字符串"
val md5hash1 = digest.digest(text.getBytes).map("%02x".format(_)).mkString

2.SHA1加密

算法原理

SHA-1是一种数据加密算法,该算法的思想是接收一段明文,然后以一种不可逆的方式将它转换成一段(通常更小)密文,也可以简单的理解为取一串输入码(称为预映射或信息),并把它们转化为长度较短、位数固定的输出序列即散列值(也称为信息摘要或信息认证代码)的过程。

单向散列函数的安全性在于其产生散列值的操作过程具有较强的单向性。如果在输入序列中嵌入密码,那么任何人在不知道密码的情况下都不能产生正确的散列值,从而保证了其安全性。SHA将输入流按照每块512位(64个字节)进行分块,并产生20个字节的被称为信息认证代码或信息摘要的输出。

该算法输入报文的长度不限,产生的输出是一个160位的报文摘要。输入是按512 位的分组进行处理的。SHA-1是不可逆的、防冲突,并具有良好的雪崩效应。

通过散列算法可实现数字签名实现,数字签名的原理是将要传送的明文通过一种函数运算(Hash)转换成报文摘要(不同的明文对应不同的报文摘要),报文摘要加密后与明文一起传送给接受方,接受方将接受的明文产生新的报文摘要与发送方的发来报文摘要解密比较,比较结果一致表示明文未被改动,如果不一致表示明文已被篡改。

转自:点击打开链接

代码如下:

[code]  def getSha1(encryptStr: String): String = try {
if (StringUtils.isBlank(encryptStr)) return null
//指定sha1算法
val digest = MessageDigest.getInstance("SHA-1")
digest.update(encryptStr.getBytes)
//获取字节数组
val messageDigest = digest.digest
// Create Hex String
val hexString = new StringBuffer
// 字节数组转换为 十六进制 数
var i = 0
while ( {
i < messageDigest.length
}) {
val shaHex = Integer.toHexString(messageDigest(i) & 0xFF)
if (shaHex.length < 2) hexString.append(0)
hexString.append(shaHex)

{
i += 1; i - 1
}
}
// 转换为全大写
hexString.toString.toUpperCase
} catch {
case e: Exception =>
e.printStackTrace()
throw new Exception(e)
}

3.AES加密算法

 

AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同,如下表所示:

AES 密钥长度(32位比特字) 分组长度(32位比特字) 加密轮数
AES-128 4 4 10
AES-192 6 4 12
AES-256 8 4 14

轮数在下面介绍,这里实现的是AES-128,也就是密钥的长度为128位,加密轮数为10轮。 

上面说到,AES的加密公式为C = E(K,P),在加密函数E中,会执行一个轮函数,并且执行10次这个轮函数,这个轮函数的前9次执行的操作是一样的,只有第10次有所不同。也就是说,一个明文分组会被加密10轮。AES的核心就是实现一轮中的所有操作。

代码如下:

[code] def desEncrypt: String = try {
//加密内容
val data = "内容"
//加密秘钥
val key = "1234567812345678"
//加密偏移量
val iv = "1234567812345678"
val encrypted1 = new BASE64Decoder().decodeBuffer(data)
val cipher = Cipher.getInstance("AES/CBC/NoPadding")
val keyspec = new SecretKeySpec(key.getBytes, "AES")
val ivspec = new IvParameterSpec(iv.getBytes)
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec)
val original = cipher.doFinal(encrypted1)
//返回结果
val originalString = new String(original)
originalString
} catch {
case e: Exception =>
e.printStackTrace()
null
}

 

 

 

 

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: