• go实现服务授权


    描述:实现服务授权,通过对称加密算法AES和分组模式CFB(密文反馈模式)实现。目前的加密算法很多,包括对称加密,非对称加密,单向散列函数。下面来分析为什么采用这种方式实现。

    Ⅰ.业务需求,明文承以下形式:

    2018-08-08&&&&&xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&&&&&2018-12-12

    当天时间                内容随意,不要出现 & 分隔符即可,一旦生成,不可更改                  服务截至日期

    密文解码后,其 &&&&& 之前的内容要与明文中 &&&&& 之前的内容完全相同,才能使用密文中的截至日期,保证授权成功。

    Ⅱ.加密算法:

    1.对称加密:

    算法:

    ①DES:通过撞库的方式,曾被暴力破解

    ②3DES:实现3次des加密,第二次加密其实是解密,是为了兼容之前DES的加密算法,数据安全性是提高了,但是3次的加密导致效率低了

    ③AES:效率高,推荐使用

    分组模式:

    ①ECB(电子密码本):对明文进行分组加密,若其中的一组被破解,其余的不言而喻,不安全

    ②CBC(密文分组链接模式):先对初始向量进行按位异或操作,再对明文分组1进行加密操作生成密文分组1,再将密文分组1以初始向量的形式操作。但是最后一组明文分组的长度未达到规定长度,需要进行补位

    ③CFB(密文反馈模式):与CBC类似,按位异或操作和加密操作的顺序交换,这样即使明文分组长度不够,也不用补位,符合业务需求

    ④OFB(输出反馈模式):不断对初始向量进行加密,导致明文中绿色的部分永远不会改变,密文的安全性降低

    ⑤CTR(计数器模式):只是对计数器进行加密,与④中的担心一样

    2.非对称加密:

    RSA:正因为担心网络传输的不安全性,怕密钥泄漏,才有了公钥和私钥的概念。服务授权不涉及密钥的网络传输。

    3.单项散列函数

    MD5,SHA1,SHA256,SHA512

    只能加密,不能解密

    代码如下:

    //aes(加密算法) + CFB(分组模式)
    
    /*
    加密
    - 参数1:明文
    - 参数2:密钥,aes规定密钥为16,24或32字节
    - 参数3:初始向量,初始向量长度和明文分组相同,即16字节
     */
    func EncodeAesCFB(src, key, iv []byte) []byte {
    	/*
    	1.加密算法
    	2.分组模式
    	3.明文和密文进行异或运算
    	*/
    	block, _ := aes.NewCipher(key)
    	stream := cipher.NewCFBEncrypter(block, iv)
    	stream.XORKeyStream(src, src)
    	return src
    }
    
    /*
    解密
    - 参数1:密文
    - 参数2:密钥,aes规定密钥为16,24或32字节
    - 参数3:初始向量,初始向量长度和明文分组相同,即16字节
     */
    func DecodeAesCFB(src, key, iv []byte) []byte {
    	/*
    	1.加密算法
    	2.分组模式
    	3.明文和密文进行异或运算
    	*/
    	block, _ := aes.NewCipher(key)
    	stream := cipher.NewCFBDecrypter(block, iv)
    	stream.XORKeyStream(src, src)
    	return src
    }
    
    /*
    服务授权时间加密
    -参数1:服务到期时间
    */
    func GenerateCipher(dateString string) string{
    	//明文
    	plainText := time.Now().Format("2006-01-02")+"&&&&&skjdsahdfwieurjow;ilhfnskjvckkxja;skdfja;sdfhaghjuijnkvn;kjfn;ahfaiugjhwoij;qqwieuityeuir&&&&&"+dateString
    	//密钥
    	key := "poiuytrewqpoiuytrewqpoiuytrewqqq"
    	//初始向量
    	iv := "poiuytrewqpoiuyt"
    	//加密
    	dst := EncodeAesCFB([]byte(plainText), []byte(key), []byte(iv))
    	//加密之后,有些字节不在acsii码中,会出现乱码。base64编码后会将字节缩短到64字节之内,防止乱码
    	rst := base64.StdEncoding.EncodeToString(dst)
    	return rst
    }
    
    /*
    获取密文中的服务到期时间
    -参数1:密文
    */
    func GetDueTime(cipherText string) (string,error) {
    	plainTextPrefix := time.Now().Format("2006-01-02")+"&&&&&skjdsahdfwieurjow;ilhfnskjvckkxja;skdfja;sdfhaghjuijnkvn;kjfn;ahfaiugjhwoij;qqwieuityeuir"
    	key := "poiuytrewqpoiuytrewqpoiuytrewqqq"
    	iv := "poiuytrewqpoiuyt"
    	b, _ := base64.StdEncoding.DecodeString(cipherText)
    	plainText := string(DecodeAesCFB(b, []byte(key), []byte(iv)))
    	//密文中包含明文前缀,获取截至日期,否则返回错误
    	if plainText[:strings.LastIndex(plainText, "&&&&&")] == plainTextPrefix {
    		dueTime := plainText[strings.LastIndex(plainText, "&&&&&")+len("&&&&&"):]
    		return dueTime,nil
    	}else{
    		return "",errors.New("incorrect code")
    	}
    }
    

      

  • 相关阅读:
    TP
    vim manual 个人笔记
    关于动画属性
    过渡
    关于 css3 的filter属性
    html 中行内元素和块级元素区别
    JS以不同的格式保存文件内容
    64位Kali无法顺利执行pwn1问题的解决方案
    鱼龙混杂 · 数据结构学习笔记(01)
    Terminal(终端) 在 OS X下如何快速调用
  • 原文地址:https://www.cnblogs.com/asceticmonks/p/13267201.html
Copyright © 2020-2023  润新知