實驗目標:
掌握區塊鏈中密碼技術的工作原理。在基于Flask框架的服務端中實現哈希算法的加密功能。
實驗內容:
構建Flash Web服務器,實現哈希算法、非對稱加密算法的加密功能。
實驗步驟:
- 哈希算法的應用:創建hash_util.py文件,然后把相關代碼輸入文件,通過命令行執行如下命令“python hash_util.py”,得到”Hello World”哈希加密后結果。
- 引入hashlib 依賴包(默認已安裝)
- 定義需要加密的變量“Hello World”
- 通過hashlib 的sha256 方法加密
- 最后輸出加密結果
- 非對稱密碼算法的應用:創建crypto_util.py文件,然后把相關代碼輸入文件,實現ECC算法的簽名與驗簽
- 安裝ecdsa 依賴包,執行命令“pip install ecdsa”
- Ecdsa方法介紹:
- SigningKey/VerifyingKey
- s=sk.to_string()/SigningKey.from_string(s, curve)
- sk.to_pem() /SigningKey.from_pem()
- sign()/verify()
- 在服務器中實現加密功能
- 構建哈希算法的處理函數
在實驗一simple_app項目中加入services.py,并在其中加入哈希算法的加密功能,相關代碼如下:
import hashlib
def hash_encrypt(input):
????"""
????使用哈希算法加密
????:param input: 客戶端發送的數據
????:return: 返回給客戶端的加密數據
????"""
????hash_code = hashlib.sha256(input.encode()).hexdigest()
????return hash_code
- 在app.py文件中加入哈希算法處理的HTTP請求響應
@app.route('/encrypt', methods=['GET'])
def encrypt():
????"""
????哈希函數加密
????:return: 加密的字典對象
????"""
????data = request.args.get('data')
????res = services.hash_encrypt(data)
????return {
????????'res': res
}
注意,一定要引用services
使用Postman驗證接口正確性
實驗
- 利用ECC實現對“學號姓名”的簽名和驗簽。
from ecdsa import SigningKey, VerifyingKey, NIST256p
import hashlibdef generate_keys():"""生成ECC密鑰對"""private_key = SigningKey.generate(curve=NIST256p)public_key = private_key.get_verifying_key()return private_key, public_keydef sign_message(message, private_key):"""使用私鑰對消息進行簽名"""# 對消息進行哈希message_hash = hashlib.sha256(message.encode()).digest()# 使用私鑰簽名signature = private_key.sign(message_hash)return signaturedef verify_signature(message, signature, public_key):"""使用公鑰驗證簽名"""try:# 對消息進行哈希message_hash = hashlib.sha256(message.encode()).digest()# 驗證簽名public_key.verify(signature, message_hash)return Trueexcept:return Falsedef main():# 要簽名的消息message = "lvy"# 生成密鑰對private_key, public_key = generate_keys()# 簽名signature = sign_message(message, private_key)# 驗證簽名is_valid = verify_signature(message, signature, public_key)# 打印結果print("消息:", message)print("私鑰:", private_key.to_string().hex())print("公鑰:", public_key.to_string().hex())print("簽名:", signature.hex())print("驗證結果:", "簽名有效" if is_valid else "簽名無效")# 嘗試使用錯誤的消息驗證wrong_message = "023301794114明浩東1"is_valid_wrong = verify_signature(wrong_message, signature, public_key)print("\n使用錯誤消息驗證:")print("消息:", wrong_message)print("驗證結果:", "簽名有效" if is_valid_wrong else "簽名無效")if __name__ == "__main__":main()
2.利用HTTP接口實現GET加密消息為:學號+姓名。
from flask import Flask, jsonify, request
from ecdsa import SigningKey, VerifyingKey, NIST256p
import hashlib
import jsonapp = Flask(__name__)# 全局變量存儲密鑰對
private_key = None
public_key = None
signature = Nonedef generate_keys():"""生成ECC密鑰對"""global private_key, public_keyprivate_key = SigningKey.generate(curve=NIST256p)public_key = private_key.get_verifying_key()return private_key, public_keydef sign_message(message):"""使用私鑰對消息進行簽名"""global private_key, signatureif private_key is None:private_key, _ = generate_keys()# 對消息進行哈希message_hash = hashlib.sha256(message.encode()).digest()# 使用私鑰簽名signature = private_key.sign(message_hash)return signaturedef verify_signature(message, signature):"""使用公鑰驗證簽名"""global public_keyif public_key is None:_, public_key = generate_keys()try:# 對消息進行哈希message_hash = hashlib.sha256(message.encode()).digest()# 驗證簽名public_key.verify(signature, message_hash)return Trueexcept:return False@app.route('/encrypt', methods=['GET'])
def encrypt():"""通過GET參數獲取要加密的數據"""data = request.args.get('data', 'lvy') # 如果沒有提供data參數,使用默認值# 對數據進行哈希加密encrypted = hashlib.sha256(data.encode()).hexdigest()return jsonify({"res": encrypted})@app.route('/get_encrypted_student_info', methods=['GET'])
def get_encrypted_student_info():"""獲取加密后的學號和姓名信息"""student_info = "lvy"# 確保有密鑰對if private_key is None:generate_keys()# 簽名消息signature = sign_message(student_info)return jsonify({'status': 'success','student_info': student_info,'signature': signature.hex(),'public_key': public_key.to_string().hex()})@app.route('/generate_keys', methods=['GET'])
def api_generate_keys():"""生成新的密鑰對"""private_key, public_key = generate_keys()return jsonify({'status': 'success','private_key': private_key.to_string().hex(),'public_key': public_key.to_string().hex()})@app.route('/sign', methods=['POST'])
def api_sign():"""對消息進行簽名"""data = request.get_json()if not data or 'message' not in data:return jsonify({'status': 'error', 'message': '請提供消息內容'}), 400message = data['message']signature = sign_message(message)return jsonify({'status': 'success','message': message,'signature': signature.hex(),'public_key': public_key.to_string().hex()})@app.route('/verify', methods=['POST'])
def api_verify():"""驗證簽名"""data = request.get_json()if not data or 'message' not in data or 'signature' not in data:return jsonify({'status': 'error', 'message': '請提供消息和簽名'}), 400message = data['message']signature_hex = data['signature']try:signature = bytes.fromhex(signature_hex)except:return jsonify({'status': 'error', 'message': '簽名格式錯誤'}), 400is_valid = verify_signature(message, signature)return jsonify({'status': 'success','message': message,'is_valid': is_valid})if __name__ == '__main__':# 初始化密鑰對generate_keys()app.run(debug=True, port=5000)