zoukankan      html  css  js  c++  java
  • 加密算法详解

    一、加密算法分为对称加密、非对称加密和散列算法 

    1.对称加密算法:加密与解密的密钥相同,算法主要有DES、3DES、AES;AES、DES、3DES都是对称的块加密算法,加解密的过程是可逆的
    	a.数据加密过程:在对称加密算法中,数据发送方将明文(原始数据)和加密密钥一起经过特殊加密处理,生成复杂的加密密文进行发送
    	b.据解密过程:数据接收方收到密文后,若想读取原数据,则需要使用加密使用的密钥及相同算法的逆算法 对加密的密文进行解密,才能使其恢复成可读明文
    
    2.非对称加密算法:加密与解密的密钥不同,算法主要有RSA、DSA
    	a.如果使用 公钥 对数据 进行加密,只有用对应的 私钥 才能 进行解密
    	b.如果使用 私钥 对数据 进行加密,只有用对应的 公钥 才能 进行解密
    	
    3.散列算法:不需要密钥,算法主要有SHA-1、MD5
    

    二、md5算法(不可逆)

      md5用的是哈希函数,它的典型应用是对一段信息产生信息摘要,所以严格来说md5是摘要算法。无论有多长的输入,md5的输出长度为128bits消息摘要(通常用16进制表示,16进制占4位,即128/4=32个字符)

      例子:

    import hashlib
    1.第一种
    m=hashlib.md5()
    m.update('nba'.encode(encoding='utf-8'))
    n = m.hexdigest()
    
    2.第二种
    hashlib.md5('nba'.encode(encoding='utf-8')).hexdigest()
    
    3.第三种
    hashlib.new('md5', 'nba'.encode(encoding='utf-8')).hexdigest()
    

      

    三、sha1算法(不可逆)

      sha1是和md5一样的摘要算法,然而sha1比md5的安全性更强。对于长度小于 2^64 位的输入,sha1的输出长度为160位的消息摘要 (通常用16进制表示,16进制占4位,即160/4=40个字符)

      例子:

    import hashlib
    1.第一种
    s=hashlib.sha1()
    s.update('nba'.encode(encoding='utf-8'))
    n = s.hexdigest()
    
    2.第二种
    hashlib.sha1('nba'.encode(encoding='utf-8')).hexdigest()
    
    3.第三种
    hashlib.new('sha1', 'nba'.encode(encoding='utf-8')).hexdigest()
    

    四、base64算法

      Base64是一种基于64个可打印字符("A-Z、a-z、0-9、+、/")来表示二进制数据的表示方法。64个字符都用6个bit位表示,一个字节有8个bit位,剩下两个bit就浪费掉了,这样就不得不牺牲一部分空间了

    base64编码对应表

      8和6的最小公倍数是24,也就是说3个传统字节可以由4个Base64字符来表示,保证有效位数是一样的,这样就多了1/3的字节数来弥补Base64只有6个有效bit不足。你也可以说用两个Base64字符也能表示一个传统字符,但是采用最小公倍数的方案其实是最减少浪费的。 结合下边的图比较容易理解。Man是三个字符,一共24个有效bit,只好用4个Base64字符来凑齐24个有效位。红框表示的是对应的Base64,6个有效位转化成相应的索引值再对应 Base64字符表,查出"Man"对应的Base64字符是"TWFU"。说到这里有个原则不知道你发现了没有,要转 换成Base64的最小单位就是三个字节,对一个字符串来说每次都是三个字节三个字节的转换,对应的是Base64的四个字节。这个搞清楚了其实就差不多了

      但是转换到最后你发现不够三个字节了怎么办呢?我们可以用两个Base64来表示一个字符或用三个Base64表示两个字符,像下图的A对应的第二个Base64的二进制位只有两个,把后边的四个补0就是了。所以 A对应的Base64字符就是QQ。上边已经说过了,原则是Base64字符的最小单位是四个字符一组,那这才两个字符,后边补两个"="吧。其实不用"="也不耽误解码,之所以用"=",可能是考虑到多段编码 后的Base64字符串拼起来也不会引起混淆。由此可见 Base64字符串只可能最后出现一个或两个"=",中间是不可能出现"="的

      例子:

    import base64
    base64.b64encode('nbawnba'.encode(encoding='utf-8'))
    base64.b64decode(b'bmJhd25iYQ==').decode('utf-8')
    

      

    五、AES算法(可逆)

      AES 加密算法是密码学中的高级加密标准,该加密算法采用对称分组密码体制,密钥长度的最少支持为128 位、192 位、256 位,分组长度为128位

      例子:

    pip install pycryptodome -i http://pypi.douban.com/simple --trusted-host=pypi.douban.com
    from Crypto.Cipher import AES
    def aes_encrypt(key, value):
        """
        aes加密
        :param key:open_key
        :param value:加密的data
        :return:
        """
        # 补足字符串长度为16的倍数
        def add_to_16(s):
            while len(s) % 16 != 0:
                s += (16 - len(s) % 16) * chr(16 - len(s) % 16)
            return str.encode(s)  # 返回bytes
    
        aes = AES.new(str.encode(key), AES.MODE_ECB)
        encrypted_text = str(base64.encodebytes(aes.encrypt(add_to_16(value))), encoding='utf8').replace('
    ', '')  #加密明文,并将返回的字节型数据转进行base64编码,
    并将字节型数据转换成python中的字符串类型 return encrypted_text def aes_decrypt(key, value): """ aes解密 :param key: open_key :param value: 需要解密的data :return: """ aes = AES.new(str.encode(key), AES.MODE_ECB) decrypted_text = aes.decrypt(base64.decodebytes(bytes(value, encoding='utf8'))).decode("utf8") # 解密 decrypted_text = decrypted_text[:-ord(decrypted_text[-1])] # 去除多余补位 return decrypted_text

      

    六、RSA算法

    加密是为了防止信息被泄露,而签名是为了防止信息被篡改。总之,公钥加密、私钥解密、私钥签名、公钥验签

    RSA的加密过程如下:

    (1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取

    (2)A传递自己的公钥给B,B用A的公钥对消息进行加密

    (3)A接收到B加密的消息,利用A自己的私钥对消息进行解密


    RSA签名的过程如下:

    (1)A生成一对密钥(公钥和私钥),私钥不公开,A自己保留。公钥为公开的,任何人可以获取

    (2)A用自己的私钥对消息加签,形成签名,并将加签的消息和消息本身一起传递给B

    (3)B收到消息后,在获取A的公钥进行验签,如果验签出来的内容与消息本身一致,证明消息是A回复的

    #生成公私钥
    import rsa
    # 生成密钥
    (pubkey, privkey) = rsa.newkeys(1024)
    # 保存密钥
    with open('public.pem' ,'w+') as f:
        f.write(pubkey.save_pkcs1().decode())
    with open('private.pem' ,'w+') as f:
        f.write(privkey.save_pkcs1().decode())
    #导入密钥
    with open('public.pem' ,'r') as f:
    	pubkey = rsa.PublicKey.load_pkcs1(f.read().encode())
    with open('private.pem' ,'r') as f:
    	privkey = rsa.PrivateKey.load_pkcs1(f.read().encode())
    
    #加密rsa
    def rsa_encrypt(message):
        crypto_email_text = rsa.encrypt(message.encode(), pubkey)
        return crypto_email_text
    text = rsa_encrypt("hello world")
    
    #解密rsa
    def rsa_decrypt(message):
        message_str = rsa.decrypt(message,privkey).decode()
        return message_str
    rsa_decrypt(text)
    #签名
    message = '这是重要指令:...'
    crypto_email_text = rsa.sign(message.encode(), privkey, 'SHA-1')
    #验签
    rsa.verify(message.encode(), crypto_email_text, pubkey)
  • 相关阅读:
    租户功能
    async await
    IOptions and context
    Setting Management: 用于持久化设置Setting值
    设置模块
    vs2017单元测试没反应,检测出错误,有关详细信息,请查看“测试输出”窗口
    自定义JS组件+调用restfui接口显示(SpringBoot)
    flex布局采用justify-content:space-between时,当为两个内容时中间被空出的解决方案
    CSS3 边框彩虹跑马灯
    react native 调试时,调出DEV菜单
  • 原文地址:https://www.cnblogs.com/konglingxi/p/13205171.html
Copyright © 2011-2022 走看看