哈希值+非对称加密+网络+数字签名,你真的知道怎么给游戏充钱吗
前文
使用socket實(shí)現(xiàn)局域網(wǎng)不同主機(jī)通信
SHA256算法的實(shí)現(xiàn)和消息的哈希散列值計(jì)算
python實(shí)現(xiàn)RSA算法,對(duì)數(shù)據(jù)進(jìn)行加密認(rèn)證
文章目錄
- 數(shù)字簽名與認(rèn)證
- 攻擊類型
- 算法選擇
- 實(shí)現(xiàn)流程
- 總結(jié)
數(shù)字簽名與認(rèn)證
什么是數(shù)字簽名?
??簽名我們大家都知道,A在紙上簽上自己的名字,其余人在紙上看到A的簽名,確認(rèn)是A的字跡,那么就可以確定這個(gè)簽名是A留下的。
??但是如何確保這是A本人簽上去的而不是第三方偽造的呢?
??這要依賴于A的習(xí)慣和字跡是有鮮明特征,與他人不同的??稍诮?jīng)過反復(fù)訓(xùn)練后,第三方仍然可以模仿A的字跡進(jìn)行簽名。
??數(shù)字簽名同樣是代表A身份的一個(gè)簽名,但是由于數(shù)據(jù)量的龐大,第三方幾乎不可能(或者說短時(shí)間內(nèi)不可能)偽造出A的簽名,這在一定程度上比我們一般知道的手寫簽名要安全、可靠。
加密和解密
??在密碼學(xué)中,我們有一套加密方法,與之對(duì)應(yīng)有一套解密方法,發(fā)送方使用加密方法對(duì)信息(稱作明文)加密,加密后的信息形成密文,將密文暴露在公共環(huán)境下,任何人都可以有機(jī)會(huì)獲得這條密文。但是加密后的密文與明文幾乎沒有關(guān)聯(lián),沒有經(jīng)過授權(quán)的人無法解讀密文的內(nèi)容,而授權(quán)用戶對(duì)密文進(jìn)行解密,得到明文(原文),才能讀懂信息。
認(rèn)證
??上述已經(jīng)了解到什么是解密和解密,但是在這個(gè)過程中,發(fā)送方無法確定接收方能否接收到信息并解密。接收方也無法確定消息是否真的是發(fā)送方發(fā)送,而不是第三方偽造。
??也就是說,發(fā)送方可以抵賴發(fā)送這條消息的真實(shí)性,接收方無法確認(rèn)這條消息是否被主動(dòng)攻擊過(偽造、篡改)。
??或許你已經(jīng)想到,有一個(gè)可靠的第三方來確認(rèn)雙方的身份和消息的安全,但這也不是絕對(duì)安全,因?yàn)閱栴}轉(zhuǎn)到了如何確認(rèn)可靠的第三方是否可靠上面。
??現(xiàn)在介紹一種方法:先將要發(fā)送的消息M經(jīng)過不可逆的運(yùn)算變成H。確保在得到H后,無法反推出原文M;確保每一個(gè)原文M,都只對(duì)應(yīng)唯一一個(gè)H,當(dāng)原文發(fā)生任何改變后,得到的H都完全不一樣。隨后,發(fā)送方使用自己的簽名方法對(duì)H進(jìn)行加密形成密文C。原文M和密文C一起發(fā)送給接收方。接收方接收到M和C,使用同樣的不可逆算法計(jì)算M得到H,再對(duì)C使用與發(fā)送方簽名方法相對(duì)應(yīng)的解密方法進(jìn)行解密,得到D,對(duì)比D和H,如果D和H一樣,則認(rèn)證成功。
??在這個(gè)過程中,這條消息無法被修改,因?yàn)槿魏我稽c(diǎn)的改動(dòng)都會(huì)導(dǎo)致產(chǎn)生很大差別的H。同時(shí),發(fā)送方無法抵賴他發(fā)送過這條消息的存在性,因?yàn)镠唯一而且只有發(fā)送方才能對(duì)H簽名成C,C也是不可修改的,接收方收到的C解密后與H一致。
??那么這和游戲充值有什么關(guān)系呢?不難發(fā)現(xiàn),網(wǎng)絡(luò)支付都需要這種手段去認(rèn)證支付記錄。假設(shè)A要想B發(fā)起一筆交易,B想要認(rèn)證這筆交易的完整性和這筆交易確實(shí)是A發(fā)起的,就需要上述簽名認(rèn)證技術(shù)。
攻擊類型
??如果第三方要偽造信息和簽名方法,需要找到一條和發(fā)送方發(fā)送的信息不一樣,但是經(jīng)過不可逆算法計(jì)算出來的H一樣?;蛘吒鶕?jù)已知的發(fā)送信息M和H簽名后的C,逆推出發(fā)送方使用的簽名方法。
算法選擇
??計(jì)算消息的唯一對(duì)應(yīng)值,可以說是信息摘要,可以使用的是MD5、DES、SHA等算法,但是這些算法不是絕對(duì)可靠的,表現(xiàn)在他們會(huì)發(fā)生碰撞(兩個(gè)不同的消息得到相同的信息摘要)。對(duì)摘要進(jìn)行加密,可以使用RSA和ECC。
??在本文實(shí)現(xiàn)中采用SHA256和RSA方法,前文鏈接SHA、RSA。同時(shí),我們要模擬發(fā)送方和接收方在網(wǎng)絡(luò)上進(jìn)行數(shù)據(jù)的傳輸,使用到網(wǎng)絡(luò)連接的方法。
實(shí)現(xiàn)流程
??首先需要模擬一個(gè)發(fā)送方和一個(gè)接收方,它們?cè)诰W(wǎng)上進(jìn)行在線支付,那就使用網(wǎng)絡(luò)連接協(xié)議,創(chuàng)建一個(gè)游戲官方服務(wù)器和一個(gè)終端玩家。
??當(dāng)玩家在游戲內(nèi)點(diǎn)擊充值時(shí),游戲的服務(wù)器給玩家發(fā)送這樣的請(qǐng)求:你給我支付648人民幣,我給你時(shí)裝道具。游戲官方確認(rèn)這筆交易并對(duì)它進(jìn)行簽名,發(fā)送給玩家。玩家接收到后,確認(rèn)這筆交易的完整,確認(rèn)發(fā)起方是游戲官方,才進(jìn)行交易的下一步。
??在服務(wù)器端,服務(wù)器對(duì)交易的內(nèi)容實(shí)驗(yàn)SHA256計(jì)算散列值,根據(jù)RSA算法使用自己的秘鑰對(duì)散列值簽名,將交易和簽名后的數(shù)據(jù)拼接在一起回送給玩家。
??玩家接收到回送數(shù)據(jù)后,檢驗(yàn)該數(shù)據(jù)是否正確,如果服務(wù)器的身份合法,則進(jìn)行后續(xù)操作。
服務(wù)器端:
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)# 處理接收到的數(shù)據(jù)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':breakserver.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 + bthash_index = int(mySHA256(bt),16)e = n = 0with 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 = 8686udpServer(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('計(jì)算的哈希值: ',cal_index)print('解密的哈希值: ', de_index)if de_index == cal_index:print('是合法的官方')else:print('非法數(shù)據(jù)')if __name__ == '__main__':address = 'localhost'port = 8686message = '充錢!648塊錢'bt = message.encode('gbk')receive = udpSend(address, port, bt)process(receive)玩家端結(jié)果
總結(jié)
使用了SHA、RSA和SOCKET實(shí)現(xiàn)網(wǎng)絡(luò)支付的一般流程,不足之處是欠缺許多功能。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的哈希值+非对称加密+网络+数字签名,你真的知道怎么给游戏充钱吗的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql binlog过期策略_对存在
- 下一篇: android support libr