实验目标:
掌握区块链中密码技术的工作原理。在基于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)