IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 哈希值+非对称加密+网络+数字签名,你真的知道怎么给游戏充钱吗 -> 正文阅读

[数据结构与算法]哈希值+非对称加密+网络+数字签名,你真的知道怎么给游戏充钱吗

前文
使用socket实现局域网不同主机通信
SHA256算法的实现和消息的哈希散列值计算
python实现RSA算法,对数据进行加密认证


数字签名与认证

什么是数字签名?

??签名我们大家都知道,A在纸上签上自己的名字,其余人在纸上看到A的签名,确认是A的字迹,那么就可以确定这个签名是A留下的。
??但是如何确保这是A本人签上去的而不是第三方伪造的呢?
??这要依赖于A的习惯和字迹是有鲜明特征,与他人不同的。可在经过反复训练后,第三方仍然可以模仿A的字迹进行签名。
??数字签名同样是代表A身份的一个签名,但是由于数据量的庞大,第三方几乎不可能(或者说短时间内不可能)伪造出A的签名,这在一定程度上比我们一般知道的手写签名要安全、可靠。

加密和解密
??在密码学中,我们有一套加密方法,与之对应有一套解密方法,发送方使用加密方法对信息(称作明文)加密,加密后的信息形成密文,将密文暴露在公共环境下,任何人都可以有机会获得这条密文。但是加密后的密文与明文几乎没有关联,没有经过授权的人无法解读密文的内容,而授权用户对密文进行解密,得到明文(原文),才能读懂信息。

认证
??上述已经了解到什么是解密和解密,但是在这个过程中,发送方无法确定接收方能否接收到信息并解密。接收方也无法确定消息是否真的是发送方发送,而不是第三方伪造。
??也就是说,发送方可以抵赖发送这条消息的真实性,接收方无法确认这条消息是否被主动攻击过(伪造、篡改)。
??或许你已经想到,有一个可靠的第三方来确认双方的身份和消息的安全,但这也不是绝对安全,因为问题转到了如何确认可靠的第三方是否可靠上面。
??现在介绍一种方法:先将要发送的消息M经过不可逆的运算变成H。确保在得到H后,无法反推出原文M;确保每一个原文M,都只对应唯一一个H,当原文发生任何改变后,得到的H都完全不一样。随后,发送方使用自己的签名方法对H进行加密形成密文C。原文M和密文C一起发送给接收方。接收方接收到M和C,使用同样的不可逆算法计算M得到H,再对C使用与发送方签名方法相对应的解密方法进行解密,得到D,对比D和H,如果D和H一样,则认证成功。
??在这个过程中,这条消息无法被修改,因为任何一点的改动都会导致产生很大差别的H。同时,发送方无法抵赖他发送过这条消息的存在性,因为H唯一而且只有发送方才能对H签名成C,C也是不可修改的,接收方收到的C解密后与H一致。

??那么这和游戏充值有什么关系呢?不难发现,网络支付都需要这种手段去认证支付记录。假设A要想B发起一笔交易,B想要认证这笔交易的完整性和这笔交易确实是A发起的,就需要上述签名认证技术。

攻击类型

??如果第三方要伪造信息和签名方法,需要找到一条和发送方发送的信息不一样,但是经过不可逆算法计算出来的H一样。或者根据已知的发送信息M和H签名后的C,逆推出发送方使用的签名方法。

算法选择

??计算消息的唯一对应值,可以说是信息摘要,可以使用的是MD5、DES、SHA等算法,但是这些算法不是绝对可靠的,表现在他们会发生碰撞(两个不同的消息得到相同的信息摘要)。对摘要进行加密,可以使用RSA和ECC。
??在本文实现中采用SHA256和RSA方法,前文链接SHARSA。同时,我们要模拟发送方和接收方在网络上进行数据的传输,使用到网络连接的方法。

实现流程

??首先需要模拟一个发送方和一个接收方,它们在网上进行在线支付,那就使用网络连接协议,创建一个游戏官方服务器和一个终端玩家。
??当玩家在游戏内点击充值时,游戏的服务器给玩家发送这样的请求:你给我支付648人民币,我给你时装道具。游戏官方确认这笔交易并对它进行签名,发送给玩家。玩家接收到后,确认这笔交易的完整,确认发起方是游戏官方,才进行交易的下一步。
??在服务器端,服务器对交易的内容实验SHA256计算散列值,根据RSA算法使用自己的秘钥对散列值签名,将交易和签名后的数据拼接在一起回送给玩家。
??玩家接收到回送数据后,检验该数据是否正确,如果服务器的身份合法,则进行后续操作。

服务器端:

def udpServer(address,port=8686):
    # dgram代表udp方式
    server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    server.bind((address, port))
    print('Server start')
    while True:
        data, ad = server.recvfrom(1024)
        # 处理接收到的数据
        print('receive from : ', ad, ' data: ', data)
        ret = serverProcess(data)
        print('send back: ',ret)
        server.sendto(ret,ad)
        c = [chr(data[i]) for i in range(5)]
        if ''.join(c) == 'close':
            break
    server.close()
    print('Server close')

def serverProcess(msg):
    msg = msg.decode('gbk')
    ret = ''
    if msg == '充钱!648块钱':
        deal = '你给我648块我就给你道具'
        bt = deal.encode('gbk')
        bt = byte2str(bt)
        ret += 'charge'
        l = len(bt)
        if len(str(l)) < 8:
            l = '0'*(8-len(str(l))) + str(l)
        else:
            l = str(l)
        ret += l + bt

        hash_index = int(mySHA256(bt),16)

        e = n = 0
        with open('e.txt', 'r') as f:
            e = int(f.read())
        with open('n.txt', 'r') as f:
            n = int(f.read())
        c = quickPowerMod(hash_index,e,n)
        ret += str(c)
    return ret.encode('utf-8')

if __name__ == "__main__":
    address = "localhost"
    port = 8686
    udpServer(address,port)

玩家端

def process(msg):
    msg = msg.decode('utf-8')
    if msg[:6] == 'charge':
        deal_len = int(msg[6:14])
        deal = msg[14:deal_len+14]
        print('deal detail: ', str2byte(deal).decode('gbk'))
        c = int(msg[deal_len+14:])
        cal_index = mySHA256(deal)

        with open('d.txt', 'r') as f:
            d = int(f.read())
        with open('n.txt', 'r') as f:
            n = int(f.read())
        de_index = quickPowerMod(c,d,n)
        de_index = hex(de_index)[2:]
        print('计算的哈希值: ',cal_index)
        print('解密的哈希值: ', de_index)
        if de_index == cal_index:
            print('是合法的官方')
        else:
            print('非法数据')

if __name__ == '__main__':
    address = 'localhost'
    port = 8686
    message = '充钱!648块钱'
    bt = message.encode('gbk')

    receive = udpSend(address, port, bt)

    process(receive)

玩家端结果
支付认证结果


总结

使用了SHA、RSA和SOCKET实现网络支付的一般流程,不足之处是欠缺许多功能。

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-02 15:06:48  更:2021-10-02 15:08:38 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 5:58:21-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码