2021-03-04-密码学基础


title: 密码学基础
date: 2021-03-04 15:29:17
categories:

  • 密码学
    tags:
  • 密码学

DES 数据加密标准

不安全 ,分组密码,8

3DES

安全,进行了3次des加密

加密过程:加密,解密,加密

解密过程:解密,加密,解密

CBC 密码块链模式

特点:密文没有规律,经常使用

最后一个明文分组需要填充

需要初始化向量-一个数组

明文分组的填充 刚好够也需要填充
填充明文分组代码实现
package main


//编写填充函数,如果最后一个分组字数不够,填充
//、、、、、字数刚好合适,添加一个新的分组
//填充的字节的值==缺少的字节数
func paddingLastGroup(plainText []byte, bloclSize int) []byte {
  //plainText 参数:明文  bloclSize 明文分组字节长度    []byte 返回值
  
//1、求出最后一个组中剩余的字节数 28%8=3..4     32%8=4.。0
  padNum:=ploclSize-len(plainText)%bloclSize //填充的字数
  //2、创建新的切片,长度==padNum, 每个字节值byte(padNum)
  char :=[]byte{byte(padNum)} //长度1,
  //切片创建,并初始化
  newPlan := bytes.Repeat(char,padNum)
  //3、newPlain数组追加到原始明文的后边
  newText := append(plainText,newPlain..)
  
  return newText
  
  
  
}
删除尾部明文分组实现
func unPaddingLastGrooup(plainText []byte) []byte {
  //1、拿去切片中的最后一个字节
  length := len(plainText)
  lastChar :=plainText[length -1]  //byte 类型
  number :=int (lastChar) //尾部填充的字节个数
  
  return plainText[:length -number]
}

对称加密实现(go)

#加密流程:
1、创建一个底层使用des/3des/aes的密码接口
"crypto/des"     
func NewCipher(key []byte) (cipher.Block, error) # -- des    
func NewTripleDESCipher(key []byte) (cipher.Block, error)   # -- 3des   "crypto/aes"   
func NewCipher(key []byte) (cipher.Block, error) # == aes 
2、如果使用的是cbc/ecb分组模式需要对明文分组进行填充
3、创建一个密码分组模式的接口对象
   - cbc
     func NewCBCEncrypter(b Block, iv []byte) BlockMode # 加密     
   - cfb    
     func NewCFBEncrypter(block Block, iv []byte) Stream # 加密 
   - ofb
   - ctr
4、加密,得到密文
DES 加密代码:
// src -> 要加密的明文 
// key -> 秘钥, 大小为: 8byte 
func DesEncrypt_CBC(src, key []byte) []byte{  
   // 1. 创建并返回一个使用DES算法的cipher.Block接口  
    block, err := des.NewCipher(key)     
   // 2. 判断是否创建成功     
    if err != nil{    
      panic(err)    
     }     
   // 3. 对最后一个明文分组进行数据填充   (明文填充)
    src = PKCS5Padding(src, block.BlockSize())    
//4. 创建一个密码分组为链接模式的, 底层使用DES加密的BlockMode接口(cbc分组接口) 
   // 参数iv的长度, 必须等于b的块尺寸    
     tmp := []byte("helloAAA")     
     blackMode := cipher.NewCBCEncrypter(block, tmp)    
   // 5. 加密连续的数据块 (加密)   
     dst := make([]byte, len(src))    
     blackMode.CryptBlocks(dst, src)
     fmt.Println("加密之后的数据: ", dst)
   // 6. 将加密数据返回 
     return dst 24
}

DES解密
// src -> 要解密的密文 
// key -> 秘钥, 和加密秘钥相同, 大小为: 8byte 
func DesDecrypt_CBC(src, key []byte) []byte { 
// 1. 创建并返回一个使用DES算法的cipher.Block接口    
    block, err := des.NewCipher(key)    
// 2. 判断是否创建成功    
    if err != nil{    
     panic(err)     
    }    
// 3. 创建一个密码分组为链接模式的, 底层使用DES解密的BlockMode接口 
    tmp := []byte("helloAAA")    
    blockMode := cipher.NewCBCDecrypter(block, tmp)  
// 4. 解密数据    
    dst := src    
    blockMode.CryptBlocks(src, dst)    
// 5. 去掉最后一组填充的数据  
    dst = PKCS5UnPadding(dst)
   // 6. 返回结果
    return dst
}

最后一个分组添加填充数据和移除添加数据代码

// 使用pks5的方式填充 
func PKCS5Padding(ciphertext []byte, blockSize int) []byte{  
// 1. 计算最后一个分组缺多少个字节  
    padding := blockSize - (len(ciphertext)%blockSize)    
// 2. 创建一个大小为padding的切片, 每个字节的值为padding   

    padText := bytes.Repeat([]byte{byte(padding)}, padding)  
// 3. 将padText添加到原始数据的后边, 将最后一个分组缺少的字节数补齐    
    newText := append(ciphertext, padText...)   
    return newText
}

// 删除pks5填充的尾部数据 
func PKCS5UnPadding(origData []byte) []byte{ 
// 1. 计算数据的总长度    
    length := len(origData)    
// 2. 根据填充的字节值得到填充的次数   
    number := int(origData[length-1])  
// 3. 将尾部填充的number个字节去掉   
    return origData[:(length-number)] 
}

测试函数

func DESText() {  
// 加密   
    key := []byte("11111111")    
    result := DesEncrypt_CBC([]byte("床前明月光, 疑是地上霜. 举头望明月, 低头思故乡."), key) 
    fmt.Println(base64.StdEncoding.EncodeToString(result))   
// 解密   
    result = DesDecrypt_CBC(result, key)  
    fmt.Println("解密之后的数据: ", string(result)) 
}

重要的函数说明

最后一个分组添加填充数据和移除添加数据代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
测试函数
重要的函数说明

1、生成一个底层使用DES加/解密的Block接口对象

函数对应的包: import "crypto/des" 
func NewCipher(key []byte) (cipher.Block, error)  
     - 参数 key: des对称加密使用的密码, 密码长度为64bit,8byte 

    - 返回值 cipher.Block: 创建出的使用DES加/解密的Block接口对象

2 、创建一个密码分组为CBC模式, 底层使用b加密的BlockMode接口对象

函数对应的包: import "crypto/cipher" 
func NewCBCEncrypter(b Block, iv []byte) BlockMode  
   - 参数 b: 使用des.NewCipher函数创建出的Block接口对象 
   - 参数 iv: 事先准备好的一个长度为一个分组长度的比特序列, 每个分组为64bit,8byte  
   - 返回值: 得到的BlockMode接口对象


  1. 使用cipher包的BlockMode接口对象对数据进行加/解密

    接口对应的包: import "crypto/cipher"
    type BlockMode interface { 
    // 返回加密字节块的大小    
    BlockSize() int    
    // 加密或解密连续的数据块,src的尺寸必须是块大小的整数倍,src和dst可指向同一内存地址    
    CryptBlocks(dst, src []byte) 
    } 
    接口中的 CryptBlocks(dst, src []byte) 方法: 
       - 参数 dst: 传出参数, 存储加密或解密运算之后的结果 
       - 参数 src: 传入参数, 需要进行加密或解密的数据切片(字符串)
    
    
  2. 创建一个密码分组为CBC模式, 底层使用b解密的BlockMode接口对象

函数对应的包: import "crypto/cipher" 
func NewCBCDecrypter(b Block, iv []byte) BlockMode 
    - 参数 b: 使用des.NewCipher函数创建出的Block接口对象 
    - 参数 iv: 事先准备好的一个长度为一个分组长度的比特序列, 每个分组为64bit,
      8byte, 该序列的值需要和NewCBCEncrypter函数的第二个参数iv值相同 
    - 返回值: 得到的BlockMode接口对象

  1. 自定义函数介绍
对称加密加密需要对数据进行分组, 保证每个分组的数据长度相等, 如果最后一个分组长度不够, 需要进行填充 
func PKCS5Padding(ciphertext []byte, blockSize int) []byte 
  - 参数 ciphertext: 需要加密的原始数据 
  - 参数 blockSize: 每个分组的长度, 跟使用的加密算法有关系 
    * des:64bit, 8byte 
    * 3des:64bit, 8byte 
    * aes: 128bit, 16byte

对称加密

对效率要求很高的时候使用对称加密

Des 3des aes

密钥分发比较困难

密钥可以用非对称加密分发

非对称加密

私钥比公钥长

公钥加密私钥解密->数据通信

私钥加密公钥解密->数字签名

保证数据完整性

防止否认

数据对谁重要,谁拿私钥

非对称加密的机密性取决于密钥长度

单向散列函数

单向散列函数 – 获取消息的指纹

有一个输入和一个输出,其中输入成为消息,输出称为散列值,单向散列函数可以根据消息的内容计算出散列值,而散列值就可以被用来检查消息的完整性。

性质

1、根据任意长度的消息计算出固定长度的散列值
2、能够快速计算出散列值
3、消息不同散列值不同
4、具备抗碰撞性。(难以发现碰撞的性质称为抗碰撞性)
5、具备单向性

消息认证码

一种确认完整性并进行认证的技术。MAC 散列值

1、需要将要发送的数据进行哈希运算

2、进行哈希运算时引入加密步骤

3、在消息认证生成的一方和校验的一方,必须有一个密钥

4.、约定使用相同的哈希函数运算

弊端

  • 密钥分发困难
    • 使用非对称加密
  • 不能第三方认证
  • 不能防止否认
消息认证码能干什么?

防止信息被修改 被盗取 消息进行加密,然后加消息认证码 进行验证 如果验证对不上,则消息被修改过。

保证数据的完整性,一致性。

数字签名

1、签名
  * 有原始数据对其进行哈希运算。->散列值
  * 使用非对称加密的私钥对散列值加密 ->签名
  * 将原始数据和签名一并发送给对方
2、验证
  * 接受数据
    # 原始数据
    # 数字签名
  * 数字签名,需要使用公钥解密,得到散列值
  * 对原始数据进行哈希运算得到新的散列值
  
数字签名是什么?

1、签名的人生成非对称加密的密钥对

2、签名的人将公钥进行分发

3、签名的人将原始数据进行哈希运算->散列值

4、签名的人使用自己的私钥对散列值进行非对称加密->最终得到的数据就是签名

证书

公钥证书:里面记有姓名、组织、邮箱地址等个人信息,以及属于此人的公钥,并由认证机构施加数字签名。公钥证书简称为证书

哈希函数

哈希函数:接受一个输入,经过计算得到一个输出,长度是固定的

可以进行数据校验、数据完整性验证、秒传

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值