实验目标:
掌握区块链中密码技术的工作原理。在基于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 hashlib
def generate_keys():
"""生成ECC密钥对"""
private_key = SigningKey.generate(curve=NIST256p)
public_key = private_key.get_verifying_key()
return private_key, public_key
def sign_message(message, private_key):
"""使用私钥对消息进行签名"""
# 对消息进行哈希
message_hash = hashlib.sha256(message.encode()).digest()
# 使用私钥签名
signature = private_key.sign(message_hash)
return signature
def verify_signature(message, signature, public_key):
"""使用公钥验证签名"""
try:
# 对消息进行哈希
message_hash = hashlib.sha256(message.encode()).digest()
# 验证签名
public_key.verify(signature, message_hash)
return True
except:
return False
def 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 json
app = Flask(__name__)
# 全局变量存储密钥对
private_key = None
public_key = None
signature = None
def generate_keys():
"""生成ECC密钥对"""
global private_key, public_key
private_key = SigningKey.generate(curve=NIST256p)
public_key = private_key.get_verifying_key()
return private_key, public_key
def sign_message(message):
"""使用私钥对消息进行签名"""
global private_key, signature
if private_key is None:
private_key, _ = generate_keys()
# 对消息进行哈希
message_hash = hashlib.sha256(message.encode()).digest()
# 使用私钥签名
signature = private_key.sign(message_hash)
return signature
def verify_signature(message, signature):
"""使用公钥验证签名"""
global public_key
if public_key is None:
_, public_key = generate_keys()
try:
# 对消息进行哈希
message_hash = hashlib.sha256(message.encode()).digest()
# 验证签名
public_key.verify(signature, message_hash)
return True
except:
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': '请提供消息内容'}), 400
message = 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': '请提供消息和签名'}), 400
message = data['message']
signature_hex = data['signature']
try:
signature = bytes.fromhex(signature_hex)
except:
return jsonify({'status': 'error', 'message': '签名格式错误'}), 400
is_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)