diff --git a/2024-shenzhen-FinTechathon/Rebirth/Contracts/DKSM.sol b/2024-shenzhen-FinTechathon/Rebirth/Contracts/DKSM.sol new file mode 100644 index 000000000..8d2cc003e --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/Contracts/DKSM.sol @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.16; + +contract DKSM { + // 用户结构体定义 + struct User { + address user; // 用户的以太坊地址 + string ID; // 用户的唯一标识符 + string Key; // 加密密钥 + string PL; // 权限列表 + string lifetime; // 生命周期 + bool login; // 登录状态 + uint256 nonce; // 随机数,用于防止重放攻击 + uint256 timestamp; // 时间戳,用于记录注册或操作时间 + mapping(string => Packet) asreq; // 存储 AS-EX 请求的映射 + mapping(string => Packet) asrep; // 存储 AS-EX 响应的映射 + mapping(string => Packet) tgsreq; // 存储 TGS-EX 请求的映射 + mapping(string => Packet) tgsrep; // 存储 TGS-EX 响应的映射 + mapping(string => Packet) apreq; // 存储 AP-EX 请求的映射 + mapping(string => Packet) aprep; // 存储 AP-EX 响应的映射 + } + + // 数据包结构体定义,用于存储消息内容和时间戳 + struct Packet { + string content; // 消息内容 + uint256 timestamp; // 消息的时间戳 + } + + address public owner; // 合约的所有者地址 + mapping(string => User) users; // 用户ID到用户信息的映射 + + // 构造函数,设置合约所有者 + constructor() { + owner = msg.sender; + } + + // 初始化用户信息的函数,仅合约所有者可以调用 + function setup(address iUser, string calldata iID, string calldata iKey, string calldata iPL, string calldata ilifetime) external { + require(msg.sender == owner); // 检查调用者是否为合约所有者 + users[iID].user = iUser; // 设置用户地址 + users[iID].ID = iID; // 设置用户ID + users[iID].Key = iKey; // 设置用户密钥 + users[iID].PL = iPL; // 设置权限列表 + users[iID].lifetime = ilifetime;// 设置生命周期 + users[iID].nonce = uint256(keccak256(abi.encodePacked(block.timestamp, block.difficulty, block.number))); // 生成随机数nonce + users[iID].timestamp = block.timestamp; // 设置时间戳 + users[iID].login = false; // 初始化登录状态为false + } + + // 获取特定用户的nonce值,用于防止重放攻击 + function get_nonce(string calldata iID) external view returns (uint256){ + require(msg.sender == users[iID].user); // 检查调用者是否为用户本人 + return users[iID].nonce; // 返回用户的nonce + } + + // 内部函数,检查提供的nonce是否与存储的nonce匹配,并递增nonce + function check_nonce(string calldata iID, uint256 _nonce) internal returns (bool) { + require(msg.sender == users[iID].user); // 检查调用者是否为用户本人 + bool Check; + if (users[iID].nonce == _nonce) { + Check = true; // nonce匹配 + } else { + Check = false; // nonce不匹配 + } + users[iID].nonce += 1; // 匹配后递增nonce + return Check; // 返回检查结果 + } + + // 返回用户的关键信息,用于验证设置的有效性 + function getInfo(string calldata iID) external view returns (address, string memory, string memory, string memory, string memory) { + return (users[iID].user, users[iID].ID, users[iID].Key, users[iID].PL, users[iID].lifetime); + } + + // 客户端设置AS-EX请求 + function C_Set_AS_REQ(string calldata IDc, string calldata IDas, string calldata AS_REQ, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + bool Check; + if (check_nonce(IDc, _nonce)) { // 检查nonce + users[IDc].asreq[IDas].content = AS_REQ; // 存储AS-EX请求内容 + users[IDc].asreq[IDas].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 认证服务器获取AS-EX请求 + function AS_Get_AS_REQ(string calldata IDc, string calldata IDas) external view returns (string memory, uint256, string memory, string memory) { + require(msg.sender == users[IDas].user); // 检查调用者是否为认证服务器用户 + return (users[IDc].asreq[IDas].content, users[IDc].asreq[IDas].timestamp, users[IDc].Key, users[IDas].Key); // 返回AS-EX请求及相关信息 + } + + // 认证服务器设置AS-EX响应 + function AS_Set_AS_REP(string calldata IDc, string calldata IDas, string calldata AS_REP, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDas].user); // 检查调用者是否为认证服务器用户 + bool Check; + if (check_nonce(IDas, _nonce)) { // 检查nonce + users[IDc].asrep[IDas].content = AS_REP; // 存储AS-EX响应内容 + users[IDc].asrep[IDas].timestamp = block.timestamp; // 设置时间戳 + users[IDc].login = true; // 更新用户登录状态为true + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 客户端获取AS-EX响应 + function C_Get_AS_REP(string calldata IDc, string calldata IDas) external view returns (string memory, uint256) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + return (users[IDc].asrep[IDas].content, users[IDc].asrep[IDas].timestamp); // 返回AS-EX响应及时间戳 + } + + //-----------------------------TGS-EX---------------------------- + // 客户端设置TGS-EX请求 + function C_Set_TGS_REQ(string calldata IDc, string calldata IDtgs, string calldata TGS_REQ, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDc].user && users[IDc].login == true); // 检查调用者是否为已登录的客户端用户 + bool Check; + if (check_nonce(IDc, _nonce)) { // 检查nonce + users[IDc].tgsreq[IDtgs].content = TGS_REQ; // 存储TGS-EX请求内容 + users[IDc].tgsreq[IDtgs].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // TGS服务器获取TGS-EX请求 + function TGS_Get_TGS_REQ(string calldata IDc, string calldata IDtgs) external view returns (string memory, uint256, string memory) { + require(msg.sender == users[IDtgs].user); // 检查调用者是否为TGS服务器用户 + return (users[IDc].tgsreq[IDtgs].content, users[IDc].tgsreq[IDtgs].timestamp, users[IDtgs].Key); // 返回TGS-EX请求及相关信息 + } + + // TGS服务器获取服务密钥 + function TGS_Get_CKv(string calldata IDtgs, string calldata IDv) external view returns (string memory) { + require(msg.sender == users[IDtgs].user); // 检查调用者是否为TGS服务器用户 + return users[IDv].Key; // 返回服务密钥 + } + + // TGS服务器设置TGS-EX响应 + function TGS_Set_TGS_REP(string calldata IDc, string calldata IDtgs, string calldata IDv, string calldata TGS_REP, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDtgs].user); // 检查调用者是否为TGS服务器用户 + bool Check; + if (check_nonce(IDtgs, _nonce)) { // 检查nonce + users[IDc].tgsrep[IDv].content = TGS_REP; // 存储TGS-EX响应内容 + users[IDc].tgsrep[IDv].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 客户端获取TGS-EX响应 + function C_Get_TGS_REP(string calldata IDc, string calldata IDv) external view returns (string memory, uint256) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + return (users[IDc].tgsrep[IDv].content, users[IDc].tgsrep[IDv].timestamp); // 返回TGS-EX响应及时间戳 + } + + //-----------------------------AP-EX---------------------------- + // 客户端设置AP-EX请求 + function C_Set_AP_REQ(string calldata IDc, string calldata IDv, string calldata AP_REQ, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + bool Check; + if (check_nonce(IDc, _nonce)) { // 检查nonce + users[IDc].apreq[IDv].content = AP_REQ; // 存储AP-EX请求内容 + users[IDc].apreq[IDv].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 服务端获取AP-EX请求 + function S_Get_AP_REQ(string calldata IDc, string calldata IDv) external view returns (string memory, uint256) { + require(msg.sender == users[IDv].user); // 检查调用者是否为服务端用户 + return (users[IDc].apreq[IDv].content, users[IDc].apreq[IDv].timestamp); // 返回AP-EX请求及时间戳 + } + + // 服务端设置AP-EX响应 + function S_Set_AP_REP(string calldata IDc, string calldata IDv, string calldata AP_REP, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDv].user); // 检查调用者是否为服务端用户 + bool Check; + if (check_nonce(IDv, _nonce)) { // 检查nonce + users[IDc].aprep[IDv].content = AP_REP; // 存储AP-EX响应内容 + users[IDc].aprep[IDv].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 客户端获取AP-EX响应 + function C_Get_AP_REP(string calldata IDc, string calldata IDv) external view returns (string memory, uint256) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + return (users[IDc].aprep[IDv].content, users[IDc].aprep[IDv].timestamp); // 返回AP-EX响应及时间戳 + } +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/Contracts/README.md b/2024-shenzhen-FinTechathon/Rebirth/Contracts/README.md new file mode 100644 index 000000000..b51585a2a --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/Contracts/README.md @@ -0,0 +1,203 @@ +## DKSM 合约接口文档 + +### 概述 + +DKSM 是一个智能合约,旨在通过去中心化的方式管理 Kerberos 服务。该合约定义了用户注册、身份验证及权限管理相关的功能,包括 AS-EX、TGS-EX 和 AP-EX 的请求与响应操作。 + +**合约版本**:Solidity 版本:^0.8.16 + +**许可证**:SPDX-License-Identifier: GPL-3.0 + +**合约所有者** + +合约所有者在部署时自动设定为合约部署者,拥有以下权限: + +* 初始化用户 (setup) +* 维护用户信息 + +**数据结构** + +**User (用户结构体)** + +| 字段 | 类型 | 描述 | +| --------- | ------- | ------------------------ | +| user | address | 用户公钥地址信息 | +| ID | string | 用户唯一标识符 | +| Key | string | 用户加密密钥 | +| PL | string | 权限列表 | +| lifetime | string | 用户生命周期 | +| login | bool | 用户登录状态 | +| nonce | uint256 | 随机数,用于防止重放攻击 | +| Timestamp | uint256 | 用户注册或者操作时间戳 | + +**Packet (数据包结构体)** + +| 字段 | 类型 | 描述 | +| --------- | ------- | ---------- | +| content | string | 消息内容 | +| timestamp | uint256 | 消息时间戳 | + +### 主要接口 + +#### 用户管理 + +**1. setup** + +初始化用户信息。 + +* **权限**: 仅合约所有者可调用 +* **输入参数**: + * iUser (address): 用户以太坊地址 + * iID (string): 用户唯一标识符 + * iKey (string): 用户加密密钥 + * iPL (string): 权限列表 + * ilifetime (string): 用户生命周期 + +* **返回值**: 无 + +**2. get_nonce** + +获取指定用户的随机数 (nonce)。 + +* **权限**: 仅用户本人可调用 +* **输入参数**: + * iID (string): 用户唯一标识符 + +* **返回值:uint256: 用户的 nonce + +**3. getInfo** + +获取用户的关键信息。 + +* **权限**: 无限制 +* **输入参数**: + * iID (string): 用户唯一标识符 +* **返回值**: + * address: 用户地址 + * string: 用户 ID + * string: 用户密钥 + * string: 权限列表 + * string: 生命周期 + +#### AS-EX (认证服务器交互) + +**1. C_Set_AS_REQ** + +设置客户端的 AS-EX 请求。 + +* **权限**: 仅用户本人可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDas (string): 认证服务器 ID + * AS_REQ (string): 请求内容 + * _nonce (uint256): 客户端当前随机数 +* **返回值**: + * bool: 操作是否成功 + +**2. AS_Get_AS_REQ** + +认证服务器获取指定客户端的 AS-EX 请求。 + +* **权限**: 仅认证服务器用户可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDas (string): 认证服务器 ID +* **返回值**: + * string: 请求内容 + * uint256: 请求时间戳 + * string: 客户端密钥 + * string: 认证服务器密钥 + +**3. AS_Set_AS_REP** + +设置认证服务器的 AS-EX 响应。 + +* **权限**: 仅认证服务器用户可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDas (string): 认证服务器 ID + * AS_REP (string): 响应内容 + * _nonce (uint256): 认证服务器当前随机数 +* **返回值**: + * bool: 操作是否成功 + +**4. C_Get_AS_REP** + +客户端获取 AS-EX 响应。 + +* **权限**: 仅客户端用户可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDas (string): 认证服务器 ID +* **返回值**: + * string: 响应内容 + * uint256: 响应时间戳 + +#### TGS-EX (票据授权服务器交互) + +**1. C_Set_TGS_REQ** + +设置客户端的 TGS-EX 请求。 + +* **权限**: 仅已登录用户可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDtgs (string): TGS 服务器 ID + * TGS_REQ (string): 请求内容 + * _nonce (uint256): 客户端当前随机数 +* **返回值**: + * bool: 操作是否成功 + +**2. TGS_Get_TGS_REQ** + +TGS 服务器获取指定客户端的 TGS-EX 请求。 + +* **权限**: 仅 TGS 服务器用户可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDtgs (string): TGS 服务器 ID +* **返回值**: + * string: 请求内容 + * uint256: 请求时间戳 + * string: TGS 服务器密钥 + +**3. TGS_Set_TGS_REP** + +设置 TGS-EX 响应。 + +* **权限**: 仅 TGS 服务器用户可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDtgs (string): TGS 服务器 ID + * IDv (string): 服务端 ID + * TGS_REP (string): 响应内容 + * _nonce (uint256): TGS 服务器当前随机数 +* **返回值**: + * bool: 操作是否成功 + +#### AP-EX (服务端交互) + +**1. C_Set_AP_REQ** + +设置客户端的 AP-EX 请求。 + +* **权限**: 仅客户端用户可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDv (string): 服务端 ID + * AP_REQ (string): 请求内容 + * _nonce (uint256): 客户端当前随机数 +* **返回值**: + * bool: 操作是否成功 + +**2. S_Get_AP_REQ** + +服务端获取 AP-EX 请求。 + +* **权限**: 仅服务端用户可调用 +* **输入参数**: + * IDc (string): 客户端 ID + * IDv (string): 服务端 ID +* **返回值**: + * string: 请求内容 + * uint256: 请求时间戳 \ No newline at end of file diff --git a/2024-shenzhen-FinTechathon/Rebirth/README.md b/2024-shenzhen-FinTechathon/Rebirth/README.md new file mode 100644 index 000000000..ea8620857 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/README.md @@ -0,0 +1,459 @@ +# 1. 项目背景 + +## 1.1 背景分析 + +随着数字经济的高速发展,数据要素已经逐步融入生产生活的各个环节,与土地、劳动力、资本、技术等并列,成为重要的生产要素之一,深刻影响并重构着经济社会结构。为应对这一变革,中国于2024年初组建国家数据局,研究并实施“数据要素X”行动,加快推进数据基础设施的建设工作[1]。数据基础设施作为让数据“供得出、流得动、用得好”的关键载体,不仅推动着数据安全可信的流通,更是实现数字服务高效利用的重要保障。 + +然而,在云计算、大数据、人工智能等新兴技术的推动下,数字服务的部署方式已发生改变。用户通过诸如Dropbox和Apple Pay等互联网服务商进行数据交互[2],但这种分布式环境也带来了新的挑战。智能设备的激增使得连接到互联网的设备数量剧增,而这些设备往往部署在不安全的环境中,使用它们的用户也并非完全可信。因此,如何确保分布式服务的安全连接成为了当下亟待解决的课题。 + +为此,基于密码学的认证方案应运而生,成为应对这些挑战的第一道防线。身份认证、数字签名交换等方案为数据安全提供了坚实保障。传统的身份认证方案可以分为两大类,基于对称密钥的Kerberos协议和基于公钥密码学的公钥基础设施(Public key infrastructure, PKI)技术。Kerberos 协议通过口令认证的方式实现对用户的认证;PKI技术,通过数字证书映射绑定以证明用户身份。然而,尽管有这些防护措施,数据安全形势依然严峻。据苹果公司近期发布的数据泄露报告,2023年前九个月就有3.6亿人的敏感数据遭泄漏,相比2022年全年高出20%。这一数字凸显了全球企业所面临的数据安全危机。 + +综上所述,数据安全已成为数字经济时代的重要议题。然而,传统的身份认证方案往往伴随着第三方的存在,中心化的认证中心难免成为黑客的首要目标,这也导致用户数据泄露事件频繁发生。传统数字交易存在的中心化及隐私保护问题日益突出,学者们尝试利用不同的技术解决现有问题。 + +2008年,中本聪一篇比特币[3]论文诞生了区块链这一项革命性的技术。区块链凭借去中心化、透明可追溯、防篡改等特性被许多学者引入,用于解决传统中心化认证方案存在的安全问题。 + +而基于区块链的去中心化认证方案作为基石,可以支撑其他研究,例如公平的数字签名交换,基于Kerberos的身份认证方案改进等的具体实施。同时出于对数字设备的性能消耗考虑,如何实现数字设备之间的高效认证也是一项挑战。因此,亟需引入区块链技术及高效的密码学方案改进优化现有的身份认证方案。 + +基于以上背景,本课题通过研究代理签名、属性基密码等加密技术,深入进行基于区块链的去中心化认证方案的研究与实现,对于解决数字设备的安全认证,实现去中心化的安全数据共享提供新思路,也为数据安全提供理论支撑,促进数据互联互通行业发展。 + + + +## 1.2 国内外相关研究现状 + +### 1.2.1 去中心化身份认证 + +中心化身份认证是当前最常见的方案,然而一旦掌控一切的中央服务器出现故障,身份识别机制就会彻底失效。区块链技术可以使身份识别机制去中心化,而不再依赖中心服务器[29]。 + +在ARPKI中,Basin等人[30]引入了多个认证中心(Certificate Authority,CA),以串行模式签名和验证证书。2014年,Fromknecht等人[31]提出了第一个基于区块链的PKI机制CertCoin。通过公开的账本记录将用户身份与公钥证书映射,从而实现PKI的去中心化。任何用户都可以查询证书的颁发过程。在此基础上,Axon等人[32]改进了CertCoin模型,并提出了一种基于区块链的PKI隐私保护技术,名为PB-PKI(基于隐私感知区块链的PKI)。不同于传统的PKI通过公钥直接连接用户的真实身份,而是通过离线密钥保护在线密钥,避免用户暴露真实身份。 + +Kubilay等人[33]提出了一种基于区块链的具有证书透明度的新的PKI模型,CertLedger。在CertLedger中,所有TLS客户端都可以验证日志的最终状态,因此不可能进行分裂世界攻击。此外,CertLedger还提供了证书撤销和受信任的CA管理流程的透明度。 + +CertChain[34]提供了一个具有证书操作历史可追溯性和撤销验证的公共审计PKI系统。为了解决被撤销的证书存储规模问题并保护客户端隐私,作者提出了一种可伸缩的证书撤销隐私保护PKI系统,PBCert。与上述基于区块链的分布式PKI系统相比不同的是,Matsumoto等人[35]研究了在给定的PKI系统中,通过自动化激励机制来抵御CA非法行为。 + +Hammi等人[36]提出了一个分布式系统,称为“信任气泡”,保证设备的可靠识别和认证,并保护数据的完整性和可用性。为了实现这一点,他们的方法依赖于区块链技术提供的安全优势,并创建安全的虚拟信任域——气泡。 + +对于分布式PKI区块链架构,Hari和Lakshman[37]实现了DNS映射中边界网关协议(BGP)的路由传播和身份验证,以防止恶意节点攻击。Faisca和Rogado[38]解决了个人云环境中的身份管理和证书管理问题,提高了认证的效率和安全性。 + +ModelChain[39]应用区块链分布式PKI在无线传感器网络中建立信任域。而Zhang等人[40]通过区块链实现安全认证,基于智能合约,以及后端软件保护扩展(SGX)可信硬件实现。Bassam等人[41]通过观察当前的X.509认证标准,只允许仅针对用户的身份颁发证书,但可以记录细粒度的身份认证证书属性信息,从而增加了属性信息的身份验证。在这种方法中,如果用户的身份信息经过身份验证,则其身份的相应属性也被认为是可信的,实现了用户身份和用户属性之间的信任交换。 + +Fabric-iot[42]是第一个通过基于区块链的ABAC模型提供细粒度访问控制的开源方案。Yao等人[43]提出了一个基于联盟链的跨域证书管理系统,CD-BCM,以简化证书撤销检查的过程。Dong Li等人[44]则提出了一种基于联盟链的车联网跨域认证协议。BTCAS[45]提出了一种基于区块链技术的彻底的跨域认证方案,可被采用完全不同设置的不同领域的参与者使用。Zhao等人[46]提出了一种基于区块链的分布式跨域身份认证协议(BC-CDIA)。将区块链证书的生成过程和哈希的存储过程放于注册过程中,减少AS和CA的验证过程,验证哈希而不是证书的签名,提高了跨域认证的效率。AAGrid[47]提出了一种基于联盟链及公钥密码的方案实现了智能电网环境下终端的身份认证和资源授权。 + +至于Kerberos改进的方案,Hena等人[48]提出了一种结合区块链技术和阈值密码系统的改进的方案。根据他们的描述,多个票单授予服务器(TGS)的部署确保了系统的可用性,并在很大程度上避免了单点故障的问题,但在该方案中没有具体实现细节。此外,他们在另一项研究中提出了一种新的基于区块链的三层认证框架[49]。设计了一个实用的拜占庭容错(PBFT)区块链网络来取代KDC的本地数据库。文献[48]解决了诸如单点故障、证书隐私和密码猜测攻击等问题。2022年,Li等人[50]针对用户和服务器之间的密钥协议提出了一种基于区块链的双向认证方案。 + +### 1.2.2 数字签名交换 + +公平交换问题指的是有两个相互不信任的当事人A和B想要交换物品,交换协议应该确保双方获得交换物品或最终不交换。随着数字经济的蓬勃发展,许多互联网上的在线业务如数字媒体,合同签署等,可能涉及双方的物品公平交换[4]。许多数字物品的所有权往往通过交换相应的数字签名来转移,因此公平交换问题的主要问题便是数字签名交换。有许多研究提出了公平的数字签名交换协议。然而,它们中的大多数都需要一个值得信任的第三方(TTP),而TTP的安全性受限。 + +为了解决可信第三方(TTP)导致的安全问题,Park等人[5]提出了一种基于RSA签名方案的协议。在此方案中,发送方只将部分私钥和公钥发送给TTP进行验证,以避免第三方推断出整个私钥。然而Dodis等人[6]指出Park的方案避免不了诚实但好奇的仲裁者推断出签名者的秘钥,因此存在推理缺陷。具体地,Huang等人[7]指出Park的协议无法抵御推断攻击。即一个好奇的TTP可以从它接收到的信息中推断出整个私钥。 + +为了保证协议的安全性,Huang和Wang等人[8]据此对协议进行了改进。Huang等人针对不可信任的第三方提出P2OFE,争议解决之后仍能保证签名安全。Wang 通过应用零知识证明和陷门承诺方案,隐藏了发送到TTP的部分公钥,而不是同时发送部分公钥和私钥。然而,该方法极大地增加了计算成本和通信成本。Zhang等人[9]首先提出了抗滥用(abuse-free)的概念,并基于离散对数实现了该属性。 + +针对TTP的消耗问题,Zhai等人[10]提出了基于低存储TTP的抗滥用的两方电子合同签署协议。2019年,CSP-E2[11]提供了一种减少TTP存储的方法。然而,集中式TTP的存在仍然是一个瓶颈,很可能遭遇单点故障。 + +并发签名[12]的概念由Chen等人提出。并发签名允许两个实体生成两个签名,签名者的身份不被第三方感知,直到一方发布附加信息。该方案基于环签名[13]和指定验证者签名[14],不依赖TTP就可以实现签名交换。Susilo等人进一步提出了一个完美的并发签名方案[15]:第三方无法推断是谁签署了两个签名中的哪一个。随后,Wang等人[16]指出,Susilo等人提出的方案实际上并不是并发的,并提出了一种攻击,使原始签名者能够释放一个精心准备的keystone。相对的,他们提出了一种有效的抵御这种攻击的方法,使改进后的方案真正适合于并发签名。 + +Ferradi等人的公平合同签名方案[17]可以在没有keystones的情况下完成两方签名交换,保证了法律公平和抗滥用。然而,该方案需要双方之间的多重交互,造成了一定的安全风险。综上,数字签名交换面临的障碍之一是其效率问题。现有的相关协议很难同时保证效率的同时,也保证其他特性。 + +近年来,区块链技术被广泛应用于解决传统数据存储的中心化问题。2014年,Danushka等人[18]提出了一种基于比特币网络的用于复杂交易的乐观公平交换电子商务协议。该方案中交换的物品不会向可信第三方泄露。Ferrer Gomila等人[19]提出了第一个基于比特币的合同签订解决方案。该解决方案在成本、效率和符合安全要求方面取得了改进,但也有局限性。 + +Huang等人[20]提出了一种基于可验证的加密签名和区块链的三方公平交换协议。Zhang等人[21]同样使用可验证加密签名方案。该方案尝试通过设计以太坊智能合约[22],实现完全去除可信第三方的存在。通过将质押代币在智能合约中来确保公平,作弊玩家将受到惩罚,即被没收代币。然而该方案使用了算力消耗较大的双线性配对操作。Ferrer Gomila等人在最新的研究中[23]使用拓展椭圆曲线签名方案,该方案清晰地将总体流程分为链上和链下两部分,并强调区块链只用于当合同签署出现争议时。 + +综上可见,从参与方数量出发,现有研究可以分为两方签署,多方签署两大类。长久以来,大多协议均是针对双方合同签署。随着签署方数量的增加,协议的通信成本和复杂度急剧增加。曹等人[24]基于无证书的高效聚合签名方案,提出一个高效的多方合同签署协议。协议中在区块链上仅公开签署方的临时密钥以减少系统开销。然而杨等人[25]通过安全性分析发现,该方案无法抵抗替换公钥攻击和内部签名者的联合攻击。为了解决上述安全缺陷,提出一个改进的无证书聚合签名方案。新方案不仅在随机预言模型下基于计算性Diffie-Hellman问题满足不可伪造性,同时也能抵抗联合攻击。 + +Payeras-Capellà等人[26]提出了去除可信第三方的基于ECC的多方数字合同签署协议,虽然没有使用昂贵的双线性配对操作,但使用了零知识证明技术保证合同的隐私,开销大。Zhang等人[27]使用并发签名方案和Schnorr签名设计了一个高效的多方电子合同签署协议,然而方案中存在NTO第三方。Zhang等人[28]提出了三方合同认证和签字的方法,将加密合同上链,同时使用异构存储在本地数据库上保留了原始合同以此减轻存储压力。 + + + +## 1.3 相关理论基础 + +### 1.3.1 区块链 + +2008年,区块链作为比特币的基础技术诞生。中本聪提出的区块链的概念,是一种点对点分布式账本技术,狭义的“区块链”可以理解为由哈希链接的带时间戳的区块序列组成。尽管颇具复杂性,区块链却以去中心化、数据透明和可追溯性而闻名。如下是区块链所具有的几个关键特征: + +首先,每个节点都拥有账本的副本,并通过共识达到一致。各个节点通过如工作量证明(PoW)和权益证明(PoS)等共识算法维护这个账本,以确保所有节点之间账本的一致性。 + +其次,不可篡改。通过使用哈希实现默克尔树,区块之间通过哈希指针链接,任意的篡改都会破坏这种链式结构。链上的交易数据不可伪造,防篡改因此实现。 + +最后,智能合约。智能合约可以简单理解为在链上运行的计算机程序,智能合约的诞生使成千上万的开发人员参与到去中心化应用的建设中,推动区块链进入可编程的新时代。随着技术的发展,新的区块链平台出现。以太坊[22]使区块链可使用智能合约进行编程。智能合约并不是一个新概念,它最初是Nick Szabo的研究中[51]提出的,它代表了由参与者执行的数字承诺。当触发条件被激活时,区块链中的智能合约可以自动执行。此外,它是无TTP的,不可逆的和可追溯的。 + +为了使区块链可编程,以太坊提供了图灵完备的编程语言Solidity[52]。Solidity等高级语言编写的智能合约通过沙箱——太坊虚拟机(EVM)编译生成字节码。它们最终会被转换为由以太坊的所有节点/矿工运行的交易。要通过EVM在区块链上运行智能合约,用户应该在以太坊上支付Gas。因此,开发者都趋向于实现低Gas成本的操作,以降低交易付出的开销。智能合约的生命周期有三个部分,即创建、部署和执行[53]。 + +智能合约创建:在这个阶段,参与者开始设计智能合约并为其编写代码。所形成的代码将被验证,并应由参与者达成一致。 + +智能合约部署:在此阶段,智能合约代码将被编译并部署到区块链中。合约的部署实质是向区块链发送一个交易,随后由以太坊中的节点/矿工进行验证和确认,将合约作为区块的一部分打包到链上。 + +智能合约执行:要执行已部署的智能合约所提供的功能,可以向区块链发送一个特殊的交易。在交易中,数据根据智能合约的接口构建,并将激活触发条件。以太坊中的节点/矿工将验证和确认交易,智能合约的状态将更改。 + +随着时间的推移,区块链技术已经在金融科技、供应链管理、产品生命周期,版权保护等领域得到了广泛应用。 + +### 1.3.2 身份认证方案 + +#### 1.3.2.1 Kerberos认证协议 + +Kerberos 是一种基于对称密码实现的身份认证协议。Kerberos名称来源于西方神话中防守地狱之门的“地狱三头犬”。该协议由麻省理工学院研发,可提供域内身份认证和单点登录等,被广泛应用于各类分布式环境中。所谓“三头”,形象地道出了Kerberos 认证协议定义的三个主要角色,分别是:客户端C、服务器V和密钥分发中心KDC。其中,KDC作为可信第三方存在,它由三个组件组成,分别是:认证服务器AS、数据库DB和票据授予服务器TGS。 + +三个交换事务,分别是:认证服务交换(AS-EX),票据授予服务交换(TGS-EX),应用交换(AP-EX)。它的目的是分发密钥和凭证,同时提供身份验证。关于每个参与者的信息,如他们的 ID 和密钥,都存储在 KDC 的数据库中。 + +![img](img/wps1.jpg) + +图1 Kerberos协议认证流程图 + +Kerberos V5[54]的认证过程如图1所示。最初,每个客户端在 KDC 中注册,他们的密钥被派生到 AES 密钥中。然后 KDC 对每个客户端的 AES 密钥进行加密,并将其存储在其数据库中。认证服务交换(AS-EX)通常用于启动登录会话并为票据授予服务器获取凭证。这些凭证随后用于为其他服务器获取凭证,而不需要进一步使用客户端的密钥。票据授予服务交换(TGS-EX)用于获取给定服务器的称为“服务票据”(ST)的身份验证凭证。应用交换(AP-EX)是客户端和服务器相互认证的最后一步,服务器验证ST。如果所有检查,如ID、时间戳和nonces,成功且没有任何错误,则建立客户端和服务器之间的身份验证,并开始客户端和服务器之间的服务会话。如果发生任何错误,客户端将以“KRB-ERR”消息响应服务器。通过AS-EX的单点登录方式,合法用户可以在不显式身份验证的情况下安全地执行TGS-EX和AP-EX。有关消息格式和加密的更多细节,请参见表1[55]。 + +尽管Kerberos在身份认证中扮演着重要角色,其存在的一些问题:如中心化造成的单点故障,重放攻击,DDoS,黄金/白银票据等并没有得到很好的解决。 + +表1 Kerberos协议中的报文 + +| 报文 | 通信方向 | 报文内容 | +| ----------- | --------- | ------------------------------------------------------------ | +| **AS-REQ** | **C→AS** | **{ IDc \|\| IDtgs \|\| Time-exp \|\| Nonce\|\| Kc{TimeStamp}}** | +| **AS-REP** | **AS→C** | **Kc{Kc,tgs\|\|IDtgs\|\|Time-exp \|\|Nonce\|\|TimeStamp\|\| TGT}** | +| **TGS-REQ** | **C→TGS** | **IDv,Time-exp,Nonce\|\| TGT \|\|Authenticator1** | +| **TGS-REP** | **TGS→C** | **Kc,tgs{Kc,v,IDc,IDv,ST, Time-exp,Nonce,TimeStamp}** | +| **AP-REQ** | **C→S** | **IDc,IDv,TimeStamp, ST\|\|Authenticator2** | +| **AP-REP** | **S→C** | **Kc,v{IDc,IDv,TimeStamp}** | + +#### 1.3.2.2 基于PKI的认证 + +PKI,全称公钥基础设施(Public KeyInfrastructure),是一种由认证中心(Certification Authority, CA)支配的基于公钥密码学实现网络安全服务的机制。该安全通信机制提供了一系列的标准安全组件,由数字证书、认证中心(CA)、注册中心(RA)、证书数据库等组成,支持身份认证、消息的完整性、机密性和不可否认性,为网络应用提供可靠的安全保障。 + +数字证书:认证中心或称证书授权中心,为设备颁发一个强绑定的数字证书。证书标准一般依据X.509 v3,其中包含了公钥和被验证过的数字签名。接收方收到数据发送方发送的数字签名和证书时,可在证书中获取公钥从而验证发送方身份的有效性。一个证书的全生命周期包括:证书的申请、审批、生成/签发、发布,再到证书更新、查询和撤销、归档。 + +注册审核机构(RA):实现 PKI体制中的数字证书申请、注册和审核。 + +认证中心(CA):作为权威机构,实现对数字证书的申请、审批、发放,再到证书的更新、查询和撤销等环节管理。 + +证书数据库:存储已签发的证书及公钥,用户从数字证书库查询证书。 + +总体上看,用户预先存储有自己所信任的根CA自签名证书,用来验证与之通信的其他PKI 用户的证书链,从而可信地获得其他用户的公钥,用于各种安全服务。 + +## 1.4 应用前景分析 + +去中心化Kerberos安全服务管理方案(DKSM)在多个领域具有广泛的应用前景: + +* 物联网(IoT)安全:随着物联网设备数量的急剧增长,确保这些设备之间的安全通信变得至关重要。DKSM提供了一种去中心化的身份认证和访问控制机制,能够有效防止未授权设备访问网络资源,确保物联网环境的安全性。 +* 智能家居:智能家居系统中,各类设备和应用程序需要进行身份认证和授权。DKSM可以提供一种安全、可靠的认证机制,确保只有经过授权的用户才能访问和控制智能家居设备,提高家庭安全性。 +* 智慧城市:在智慧城市建设中,涉及到大量的分布式数据和服务管理。DKSM可以为智慧城市中的各种应用提供安全认证和访问控制,防止数据泄露和非法访问,保障城市管理系统的安全运行。 +* 云计算和边缘计算:在云计算和边缘计算环境中,数据和服务的安全性至关重要。DKSM通过去中心化的方式,实现了对用户身份的认证和对数据的细粒度访问控制,能够有效防止数据泄露和篡改,提升云计算和边缘计算环境的安全性。 + +⚫ 金融科技:在金融科技领域,用户身份认证和数据安全是关键问题。DKSM可以为金融科技应用提供高效、安全的身份认证机制,确保金融交易的安全性,防止欺诈和数据泄露。 + +⚫ 医疗健康:在医疗健康领域,患者数据的隐私保护和访问控制至关重要。DKSM通过基于属性的加密机制,实现了对患者数据的细粒度访问控制,确保只有经 + +过授权的医疗人员才能访问敏感数据,保障患者隐私安全。 + +综上所述,去中心化Kerberos安全服务管理方案(DKSM)通过结合区块链技术和密文策略属性基加密(CP-ABE)方法,为各类分布式环境提供了一种安全、高效的身份认证和访问控制解决方案,具有广泛的应用前景和重要的实际意义。 + +# 2. 项目简介 + +本作品针对Kerberos身份认证方案存在的中心化问题,链上信息隐私保护问题,提出了基于区块链的去中心化Kerberos身份认证方案(DKSM)。设计智能合约实现更高程度的去中心化,免除 KDC 的中心化存储;尝试寻找细粒度访问控制方案,对链上信息,如KDC密钥进行隐私保护和细粒度访问控制;基于密文策略的属性基密码(CP-ABE) 与对称密码AES进行结合,实现链上信息隐私保护及细粒度访问控制;设计基于区块链的时间同步应答响应机制,实现对重放攻击的抵御。基于Python实现了协议,并设计了Solidity智能合约。 + +其设计逻辑包括以下三方面: + +(1)与区块链结合紧密。**设计智能合约**实现更高程度的去中心化,免除KDC的中心化存储;基于区块链账户地址实现去中心化身份,消除了重复生成公钥对的需要。 + +(2)**采用AES和CP-ABE**作为隐私保护的密码机制。采用FABEO属性基加密算法,密文短,效率高,实现对KDC密钥的细粒度访问控制; + +(3)实现对多数传统攻击的抵御。为了抵抗重放攻击,**设计**一种基于区块链的时间同步解决**方案BCTs-Nc**;同时,区块链技术使DKSM实现对中间人攻击及白银票据,黄金票据的抵御。 + +## 2.1 系统模型 + +本作品取名DKSM(Decentralized Kerberos Secure Service-Management),即去中心化Kerberos安全服务管理协议,保留了原始Kerberos方案中的客户端,服务器以及密钥分发中心KDC三个角色,及三个交换过程。传统的KDC存在中心化问题,在KDC数据库中存储着协议参与者的私钥,一旦私钥泄露,会危及服务安全管理。因此,我们借助区块链技术引入智能合约进行存储、逻辑判断,实现去中心化的KDC。所有的交流消息都会被存进区块链智能合约中。 + +此外,DKSM融合基于密文策略的属性基加密以实现数据细粒度访问控制,对链上数据进行隐私保护。与传统的安全服务管理相比,新的方案具有以下特点:首先,去中心化,这意味着不再依赖于单一的中心机构来管理安全服务。其次,可追溯性,可以追踪到每一次操作的来源和过程。再者,隐私保护,用户信息不被泄露。最重要的是,DKSM实现了3As原则,即提供了访问控制、授权和审计三大功能。确保安全服务的全面性和可靠性。由于传统Kerberos不提供授权功能,DKSM将授权简化为包含用户ID和权限ID,操作权限的权限列表来表示权限范围。最后,通过在以太坊测试网络和FISCO的实验表明DKSM方案的可行性。 + +![img](img/wps2.jpg) + +图3 去中心化Kerberos身份认证设计总览图 + +DKSM的总览图如图3,整体协议流程如下: + +① 要加入Kerberos的域中,必须首先通过将其公共信息上传到智能合约注册。 + +② 授权机构根据制定的访问策略**S**生成ABE密钥对**PK、MSK**。验证者如果没有正确的属性,将无法获取**Kkdc**正确地解密任何用户的秘密密钥。 + +③ 接下来,KDC调用相应的初始化函数并上传用户数据。 + +④ 为了登录,客户端在发起认证事务的同时,必须发送AS-REQ消息,触发相应的函数如**get_nonce()、check_nonce()**等以抵御重放攻击。由智能合约验证客户端的合法性。 + +⑤ 如果客户端是合法的,则存储AS-REQ并等待票据授予服务器TGS检索它。当收到AS-REQ消息时,TGS执行相同的身份验证和重放防御。智能合约提供身份验证并实现对重放攻击的抵御。 + +⑥ 在解密和验证AS-REQ后,认证服务器(AS)通过AS- REP响应向客户端发出**TGT**票据。**TGT票据**允许客户端访问TGS以获得**ST**票据。 + +⑦ 客户端将使用**TGT**票据置入TGS-REQ消息来访问TGS。TGS解密身份验证码和TGT票据,以验证客户端名称是否一致,以及时间戳是否在有效范围内等。如果满足,TGS通过区块链向客户端在TGS-REP响应中发出ST票据。 + +⑧ 在接收到TGS-REP后,客户端将使用AP-REQ消息启动AP-EX。其中,AP-REQ中的身份验证码用于消息校验和和会话密钥传输。 + +⑨ 如果验证成功,服务器将在AP-REP消息中包含一个临时会话密钥**K****session**进行响应。最后,服务会话顺利进行。 + +表2 DKSM符号表 + +| 名称 | 描述 | +| ------- | ------------- | +| KDC | 密钥分发中心 | +| C | 客户 | +| V | 服务器 | +| AS | 认证服务器 | +| TGS | 票据服务器 | +| TGT | 票据授予票据 | +| ST | 服务票据 | +| REP/REQ | 请求/响应报文 | + +## 2.2 详细设计 + +DKSM可以分为“初始化”,“认证服务交换”,“票据授予服务交换”,“双向认证交换”四部分。方案的符号表如表2所示,方案使用的所有密钥及其作用如表3所示。 + +表3 DKSM密钥表 + +| 名称 | 密钥种类 | 描述 | +| ---------------- | -------- | ------------------------ | +| **K****C** | AES-256 | 客户端AES密钥 | +| **K****TGS** | AES-256 | TGS AES密钥 | +| **K****V** | AES-256 | 服务端AES密钥 | +| **K****C,TGS** | AES-256 | 客户端及TGS的会话密钥 | +| **K****C,V** | AES-256 | 客户端及服务端的会话密钥 | +| **K****session** | AES-256 | 服务会话密钥 | +| **PK** | CP-ABE | 系统属性基公钥 | +| **MSK** | CP-ABE | 系统属性基主密钥 | +| **SK** | CP-ABE | 用户属性基私钥 | + +### 2.2.1 初始化 + +l AES密钥生成:首先,每个用户(包括客户端和服务器)提供其ID和密码进行注册。用户的密钥是一个AES-256密钥,使用PBKDF2算法从密码和ID生成。 + +l 属性基密码创建:接下来,权威机构将生成一个基于密文属性的加密密钥对(**PK,MSK**),并从消息空间**M**中随机选择一条消息**m**。然后根据KDC设置的访问策略“**S**”对**KDC**进行加密。更多细节详见2.2.3节。验证者如果不具备必要的属性,那么他将无法获得正确的**KDC**来解密任何用户的密钥。 + +l 数据加密:与客户端和服务器不同,KDC负责管理所有用户的密钥,并需要将密钥公开存储在区块链上。与传统方案一致,DKSM使用**KDC**对所有用户的AES密钥和权限列表进行加密。不同之处在于,我们使用了一种基于密文策略属性的加密(CP-ABE)方案来实现对**KDC**的细粒度访问控制,这也同时在一定程度实现了去中心化。当提供了正确的属性时,将运行**KeyGen(MSK,S)**以获得用于解密的**SK**。 + +l 智能合约初始化:所设计的智能合约包括两个结构体:“User”和“Packet”,分别代表用户和其对应的报文,如表4,表4-4,表6所示。DKSM定义了一个用户id到Packet的映射,每个用户都有他对应发送的Packet(交换报文)。User用户结构被用于存储与用户的字符串ID相关联的公共信息。在DKSM中,ID相当于Kerberos中的“主体”。例如,在DKSM域中的Alice的ID是Alice@dksm.com。此外,User存储每个用户对应的随机数,用于识别消息重放。一旦部署了DKSM智能合同,KDC就可以调用算法1来上传用户的信息。 + +DKSM将KDC与智能合约结合,从而产生了一个包含区块链特征的增强Kerberos方案,不仅提供了分布式存储和消息可跟踪等好处,同时保护了数据隐私。 + +``` +算法1 Initialization + +Require: (ID, Address, EncKey, EncPL, lifetime**) +Output: True or False +1: if users[ID].id == null then +2: users[ID].id = ID; +3: users[ID].user =Address; +4: users[ID].Key = EncKey; +5: users[ID].PL = EncPL; +6: users[ID].lifetime = lifetime; +7: users[ID].nonce = uint256(keccak256(block.timestamp, block.number)); +8: users[ID].timestamp = block.timestamp; +9: users[ID].islogin = False; +10: else +11: return False;//User already exist +12: end if +13: return True; +``` + + 表4 DKSM智能合约中的主要数据结构 + +| 数据类型 | 变量名 | 内容 | +| ----------------------- | ------ | ---------------------------- | +| struct | User | The User structure | +| struct | Packet | The Packet structure | +| mapping(string => User) | users | ID to User structure mapping | + +表5 DKSM智能合约中的User数据结构 + +| 数据类型 | 变量名 | 内容 | +| ------------------------- | ------------- | --------------------------------- | +| address | **user** | The User’s address | +| string | **id** | principal | +| string | **Key** | Encrypted AES secret key | +| string | **PL** | Encrypted Permission List | +| string | **lifetime** | lifetime | +| uint256 | nonce | nonce for replay defense | +| uint256 | **timestamp** | user’s setup time | +| bool | islogin | login state | +| mapping(string => Packet) | RepOrReq | ID to Request or response mapping | + +表6 DKSM智能合约中的Packet数据结构 + +| 数据类型 | 变量名 | 内容 | +| -------- | ------------- | ------------------------ | +| address | user | The Originator’s address | +| string | **IDfrom** | principal | +| string | **IDto** | principal | +| uint | **timestamp** | block.timestamp | +| string | REQorREP | Exchange Message | + +接着,我们提出了一种基于区块链的时间同步方案,基于时间戳及随机数的概念抵御重放攻击,称为**BCTs-Nc。**该方案在每个报文上传/获取或交易的过程中运行。具体来说,我们基于区块链修改了传统Kerberos机制,结合了块数、块时间戳等特性。 + +时间戳检查:当消息上传到区块链进行存储时,智能合约将消息的时间戳设置为块时间戳**block.timestamp**(如算法3-2的第3行所示)。其核心思想在于存储时设置时间戳,并在用户检索报文时检查它。 + +随机数检查:在初始化过程中,在智能合约中设置随机数nonce,如算法4-2的第3行所示,并绑定到用户的地址。在发送消息时,每个用户必须获得一次nonce,并将其包含到报文中。接着,智能合约验证nonce是否与用户地址匹配。如果是,消息被成功接受,nonce自动增加1。如不匹配,则会拒绝该用户的上传操作。 + +``` +算法2 BCTs-Nc for Time Synchronization and Nonce-check + +Require: (IDfrom, IDto) +Output: True or False +1: while User set a message do +2: nonce_from = getnonce(IDfrom); +3: users[IDfrom].ReqOrRep[IDto].timestamp = block.timestamp; +4: if users[IDfrom].nonce == nonce_from +5: Nonce_Check = True; +6: else +7: Nonce_Check = False; +8: end if +9: users[IDfrom].nonce += 1; +10: end while +11: while User get a message do +12: nonce_to = getnonce(IDto); +13: if users[IDto].nonce == nonce_to and localtime - message_time < 300 +14: Nonce_Check = True; +15: Time_Check = True; +16: else +17: Nonce_Check = False; +18: Time_Check = False; +19: end if +20: users[IDto].nonce += 1 +21: end while +``` + +在所有用户成功注册之后,协议分别执行认证服务交换(AS-EX)、票证授予服务交换(TGS-EX)和双向认证交换(AP-EX)。 + +### 2.2.2 认证服务交换 + +当一个客户端想要访问一个特定的应用程序服务器时,它必须首先通过向KDC的认证服务器(AS)证明其身份,以获取凭据TGT。拿到TGT票据的客户端才能请求一个特定的服务。认证服务交换包含以下两个报文: + +**1)** **AS-REQ** :={ ID_C || ID, TGS || Time-exp || Nonce|| Kc{TimeStamp}}; + +**AS-REQ**报文中包含了一个加密的时间戳以及客户端和TGS的标识等。客户端通过区块链帐户发送签名交易,保证交易是无法伪造的。智能合约会首先检查报文中的两个id是否存在于用户列表中,验证id到地址绑定以防止非法登录,并执行**BCTs-Nc**算法。 + +**2)** **AS-REP**:=Kc{KC,TGS || ID, TGS ||Time-exp ||Nonce || TimeStamp || TGT}; + +其中**TGT**登录验证成功后,身份验证服务器(AS)将包含**TGT**票据的**AS-REP**发送到客户端。变量**Kc,tgs**表示一个随机生成的AES密钥,它作为客户端和票证授予服务器(TGS)之间的会话密钥。AS通过向发送事务,在智能合约中存储**AS-REQ**消息。智能合约在存储**AS-REP**并将用户的登录状态设置为“True”之前,会验证报文的各个方面,如发送者地址、消息ID等。一旦客户端接收到**AS-REP**消息,解密成功后检查,如果消息中的时间戳在可接受的范围内,则认为身份验证成功。然后,客户端保存**TGT**和会话密钥,以便将来进行通信。否则,客户端将向AS发送一个错误消息。 + +### 2.2.3 票据授予服务交换 + +成功登录后,客户端可以申请访问特定的服务器。客户端和服务器之间的消息交换包括一个请求和响应。票据授予服务交换包含以下两个报文: + +**1)** TGS-REQ := {ID_V, Time-exp, Nonce|| TGT || Authenticator1}; + +其中**Authenticator1**:= K_C, TGS{ID_C, CheckSum, TimeStamp}。 + +认证码“**Authenticator1**”向TGS证明客户端持有会话密钥,并提供(**ID_C, ID_V, TGT**)的校验和,以确保消息的完整性。同样地,当客户端发送事务时,智能合约会自动执行一系列检查。在从区块链获得**TGS-REQ**后,TGS解密了**Authenticator1**和**TGT**。如果**TGT**的生命周期在指定的范围内,并且认证码正确,则票证请求成功。最后,TGS将查找客户端的权限列表,以查看它是否有权访问该服务器。否则,交换失败,TGS将用“**KRB-ERR**”响应客户端。(如算法4所示) + +``` +算法3 TGS-EX + +Require: (ID_C, ID_V, ID_KDC, TGT) +Output: SUCCESS or ERROR +1: Authenticator1 ← Enc_K_C,TGS(ID_C|| CheckSum || Timestamp +2: TGS-REQ ← ID_C || ID_V || TimeStamp || TGT || Authenticator1; +3: Await DKSM.CSetTGS-REQ(ID_C, ID_V, ID_KDC, Nonce_C, TGS-REQ); +4: TGS-REQ, CK_KDC ← Await DKSM.TGSGetTGS-REQ(ID_C, ID_V, ID_KDC); +5: if users[ID_C].TGSREQ[ID_TGS].content != null and ContentCheck() and CheckTGT() +6: K_C,V ← GenRandKey(); +7: Decrypt TGT and get K_C,TGS +8: K_V ← Dec(DKSM.TGSGet-CKv(ID_KDC, ID_V)); +9: K_C,V ← GenRandKey(); +10: ST_V ← EncKv(ID_C, ID_V, K_C,V lifetime); +11: TGS-REP ← EncKc,tgs(K_C,V, ID_C ID_V ST_V , Nonce, TimeStamp); +12: Await DKSM.SetTGS-REP(IDc, IDv, Nonce_TGS, TGS-REP); +13: TGS-REP, TS-tgsrep ← Await DKSM.GetTGS-REP(IDc, IDv); +14: if users[ID_C].TGSREP[ID_V].content ≠ null and ContentCheck() +15: Decrypt and Get ST_V; +16: return ST_V, K_C,V; +17: else +18: return ERROR; +19: end if +20: else +21: return ERROR; +22: end if +``` + +**2)** **TGS-REP**:= {Kc,tgs{K_c, v, ID_C, ID_V, ST, Time-exp, Nonce, TimeStamp}}; + +其中**ST**:=K_V{ID_C, ID_V, K_C,V, lifetime} + +作为对**TGT**票据请求的响应,**TGS-REP**基于会话密钥**Kc,tgs**进行加密。服务票不仅包含由TGS随机生成的会话密钥**K_C,V**,还包含票的有效期。任何逾期门票均需重新申请签发。类似于**AS-REP**的接收,客户端解密消息并确认**TGS-REP**中的信息是可接受的(如算法3所示)。然后保存服务票证和会话密钥**K_C,V**,以便进行后续通信。如果对TGS-EX进程的任何验证出错,客户端将用“KRB-ERR”响应TGS。 + +### 2.2.4 双向认证交换 + +双向认证交换包含以下两个报文: + +**1)** **AP-REQ**:={IDc, IDv, TimeStamp, ST || Authenticator2}; + +与**TGS-REQ**类似,客户端需要在**AP-REQ**中发送一个身份验证码**Authenticator2**。但是,在这种情况下,身份验证器包含由客户端生成的服务会话密钥**K_session**。如果服务票据在有效期内,并且身份验证码核验正确,则服务请求成功。TGS将保存**K_C,V**和**K_session**供进一步使用。如果发生任何错误,返回“KRB-ERR”。 + +**2)**AP-REP:={Kc,v{IDc,IDv,TimeStamp}; + +服务器发送一个带有id和时间戳的响应,客户端在解密后进行检查。此外,智能合约不仅通过地址绑定ID来确保身份验证,而且还可以通过我们设计的**BCTs-Nc**算法实现重放检测。如果上述所有验证都通过,客户端和服务器之间的相互验证成功。然后,客户端和服务器可以使用临时会话密钥启动服务会话。如果任何步骤出现错误,服务器将使用“**KRB-ERR**”消息响应客户端。 + +``` +算法4 AP-EX + +Require: (ID_C, ID_V ST_V)Output: SUCCESS or ERROR +1: K_session ← GenRandKey(); +2: Authenticator2 ← EncK_C,V(IDc || CheckSum || K_session || TimeStamp1); +3: AP_REQ = ID_C || ID_V || TimeStamp2 || ST_V || Authenticator2; +4: Await DKSM.CSetAP_REQ(ID_C, ID_V. Nonce_C, AP_REQ); +5: AP_REQ ← Await DKSM.VGetAP-REQ(ID_C, ID_V); +6: if users[ID_C].APREQ[ID_V].content != null and ContentCheck() and CheckST(); +7: AP-REP ← EncKsession(ID_C || ID_V || TimeStamp); +8: Await DKSM.VSetAP-REP(ID_C , ID_V , Nonce_V, AP_-REP); +9: AP_REP ← Await DKSM.CGetAP-REP(ID_C , ID_V); +10:if users[ID_C].APREP[ID_V].content != null and ContentCheck() == True ; +11:Decrypt and Get K_session; +12:return K_session; +13: else +14: return ERROR; +15:end if +16: else +17: return ERROR; +18:end if +``` + + + +## 2.3 安全性分析 + +DKSM解决了Kerberos协议所面临的大部分安全挑战,以下是细节: + +**1. 隐私性**。数据包在被加密后存储在智能合约中。因此,没有对称密钥的用户无法访问明文数据。其次,为了防止对称密钥在传输过程中被泄露,我们使用CP-ABE算法。客户端只有经过智能合约的认证和授权后才能获得TGT票据,每个用户的权限列表由服务所有者设置。并且,DID作为其身份验证解决方案。 + +**2. 细粒度访问控制**。为了防止在交易过程中被泄露,DKSM实现了CP-ABE算法,在多个属性之间共享**KDC**。只有具有正确属性,才能解密**密文信息。 + +**3. 重放攻击抵御**。重放攻击指攻击者拦截一条消息,并恶意将这条消息重新发送给消息接收方,以通过身份验证或在网络中实施欺诈行为。常见的抵御方式有加入时间因素或者一次性验证码等,加大重放成功的难度。我们提出了一个基于区块链的时间同步解决方案,称为**BCTs-Nc**。具体来说,我们利用区块链的各种特性,如区块链账户地址作为DID,块高度,时间戳等,智能合约根据块数和块时间戳随机生成一个变化因子,变化因子阻碍了重放攻击的成功进行。 + +**4. 中间人攻击抵御**。我们的方案通过使用签名机制和证书,有效地抵抗了中间人的攻击。用户进行的每笔交易都被链接到他们的帐户地址。即使攻击者窃取了消息,他们也将无法伪造交易,因为私钥是保密的。 + +**5. 白银票据和黄金票据攻击抵御**。白银票据,黄金票据分别指代服务票据ST和认证票据TGT。白银票据攻击:攻击者获取目标服务器的NTLM哈希值,以便伪造有效的ST票据,访问特定的服务;黄金票据攻击:攻击者获取域控krbtgt的密码哈希值,用于伪造TGT票据。我们的方案建立在区块链技术之上,为用户提供身份验证,有效地禁止凭证伪造。攻击者将无法伪造或窃取DKSM协议的票据。 + + + +# 3. 创新性说明 + +本文提出的去中心化 Kerberos 安全服务管理方案(DKSM)在多个方面具有显著的创新性,主要体现在以下几个方面: + +1. 去中心化身份认证: + +DKSM 引入了基于区块链账户地址的去中心化身份(DID)认证机制,替代了传统 Kerberos 中的集中化密钥分发中心(KDC)。这种去中心化的设计消除了单点故障问题,提高了系统的可用性和可靠性。 + +2. 高级加密标准(AES)和密文策略属性基加密(CP-ABE)结合: + +DKSM 结合了 AES 和 CP-ABE 两种加密技术,既保证了数据传输的高效性,又提供了细粒度的访问控制。特别是采用了快速属性加密(FABEO)方案,该方案相比传统的 CP-ABE 方案,具有更短的密文和更高的加密解密效率。 + +3. 基于区块链的时间同步和随机数校验机制: + +DKSM 设计了一种基于区块链的时间同步和随机数校验解决方案(BCTs-Nc),有效防止了重放攻击。通过利用区块链的不可篡改性和可追溯性,确保了时间戳和随机数的安全性,进一步提升了系统的防护能力。 + +4. 智能合约实现身份认证: + +DKSM 通过智能合约实现身份认证和访问控制。智能合约的自动执行特性不仅提高了认证过程的效率,还减少了人为干预的可能性,确保了认证过程的公正性和透明性。 + +5. 跨平台的可移植性和成本效益: + +DKSM 方案在两个区块链网络(Sepolia 和 FISCO)上的实验表明,该方案具有良好的可移植性和成本效益。特别是在 FISCO BCOS 平台上,各阶段的时间成本分析表明,DKSM 在性能和成本上具有显著优势,适用于实际应用场景。 + +6. 全面的安全防护: + +DKSM 不仅解决了传统 Kerberos 协议中的密钥暴露和时间同步问题,还通过区块链和 CP-ABE 技术,提供了全面的安全防护。本文详细分析了 DKSM 在防止重放攻击、中间人攻击和票据伪造攻击等方面的优势,展示了其在安全性上的创新。 + +综上所述,本文提出的 DKSM 方案在去中心化身份认证、加密技术结合、时间同步和随机数校验、智能合约应用、跨平台可移植性以及全面安全防护等多个方面进行了创新,提供了一种高效、安全、可靠的分布式身份认证和访问控制解决方案,具有重要的理论意义和应用价值。 \ No newline at end of file diff --git a/2024-shenzhen-FinTechathon/Rebirth/img/wps1.jpg b/2024-shenzhen-FinTechathon/Rebirth/img/wps1.jpg new file mode 100644 index 000000000..96c14dcf1 Binary files /dev/null and b/2024-shenzhen-FinTechathon/Rebirth/img/wps1.jpg differ diff --git a/2024-shenzhen-FinTechathon/Rebirth/img/wps2.jpg b/2024-shenzhen-FinTechathon/Rebirth/img/wps2.jpg new file mode 100644 index 000000000..e1e7e3eb9 Binary files /dev/null and b/2024-shenzhen-FinTechathon/Rebirth/img/wps2.jpg differ diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/abi/DKSM.abi b/2024-shenzhen-FinTechathon/Rebirth/src/abi/DKSM.abi new file mode 100644 index 000000000..5e6e0a9b5 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/abi/DKSM.abi @@ -0,0 +1,533 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDas", + "type": "string" + } + ], + "name": "AS_Get_AS_REQ", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDas", + "type": "string" + }, + { + "internalType": "string", + "name": "AS_REP", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "AS_Set_AS_REP", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDv", + "type": "string" + } + ], + "name": "C_Get_AP_REP", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDas", + "type": "string" + } + ], + "name": "C_Get_AS_REP", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDv", + "type": "string" + } + ], + "name": "C_Get_TGS_REP", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDv", + "type": "string" + }, + { + "internalType": "string", + "name": "AP_REQ", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "C_Set_AP_REQ", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDas", + "type": "string" + }, + { + "internalType": "string", + "name": "AS_REQ", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "C_Set_AS_REQ", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDtgs", + "type": "string" + }, + { + "internalType": "string", + "name": "TGS_REQ", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "C_Set_TGS_REQ", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDv", + "type": "string" + } + ], + "name": "S_Get_AP_REQ", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDv", + "type": "string" + }, + { + "internalType": "string", + "name": "AP_REP", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "S_Set_AP_REP", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDtgs", + "type": "string" + }, + { + "internalType": "string", + "name": "IDv", + "type": "string" + } + ], + "name": "TGS_Get_CKv", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDtgs", + "type": "string" + } + ], + "name": "TGS_Get_TGS_REQ", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "IDc", + "type": "string" + }, + { + "internalType": "string", + "name": "IDtgs", + "type": "string" + }, + { + "internalType": "string", + "name": "IDv", + "type": "string" + }, + { + "internalType": "string", + "name": "TGS_REP", + "type": "string" + }, + { + "internalType": "uint256", + "name": "_nonce", + "type": "uint256" + } + ], + "name": "TGS_Set_TGS_REP", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "iID", + "type": "string" + } + ], + "name": "getInfo", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + }, + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "iID", + "type": "string" + } + ], + "name": "get_nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "iUser", + "type": "address" + }, + { + "internalType": "string", + "name": "iID", + "type": "string" + }, + { + "internalType": "string", + "name": "iKey", + "type": "string" + }, + { + "internalType": "string", + "name": "iPL", + "type": "string" + }, + { + "internalType": "string", + "name": "ilifetime", + "type": "string" + } + ], + "name": "setup", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] \ No newline at end of file diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/bin/DKSM.bin b/2024-shenzhen-FinTechathon/Rebirth/src/bin/DKSM.bin new file mode 100644 index 000000000..2ec706e4e --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/bin/DKSM.bin @@ -0,0 +1 @@ +608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612c0e806100606000396000f3fe608060405234801561001057600080fd5b506004361061010b5760003560e01c806384592cdb116100a25780638fafc21a116100715780638fafc21a1461033357806393d9797414610366578063944c516814610396578063a4242924146103c6578063b8ef80b1146103f65761010b565b806384592cdb14610283578063892698be146102b557806389fc674e146102e55780638da5cb5b146103155761010b565b80634691e259116100de5780634691e259146101d157806357a353f214610202578063714c89f11461021e5780637ee005ab1461024f5761010b565b80630de43d31146101105780630f4f5a5614610140578063153f62c81461017157806333089fc0146101a1575b600080fd5b61012a60048036038101906101259190612142565b610427565b6040516101379190612259565b60405180910390f35b61015a60048036038101906101559190612274565b610572565b604051610168929190612394565b60405180910390f35b61018b600480360381019061018691906123c4565b610713565b6040516101989190612259565b60405180910390f35b6101bb60048036038101906101b69190612274565b61085c565b6040516101c8919061248d565b60405180910390f35b6101eb60048036038101906101e69190612274565b61098f565b6040516101f9929190612394565b60405180910390f35b61021c6004803603810190610217919061250d565b610b30565b005b61023860048036038101906102339190612274565b610d7a565b604051610246929190612394565b60405180910390f35b61026960048036038101906102649190612609565b610f1b565b60405161027a959493929190612665565b60405180910390f35b61029d60048036038101906102989190612274565b611237565b6040516102ac939291906126d4565b60405180910390f35b6102cf60048036038101906102ca91906123c4565b61148c565b6040516102dc9190612259565b60405180910390f35b6102ff60048036038101906102fa9190612609565b6115d5565b60405161030c9190612719565b60405180910390f35b61031d61167e565b60405161032a9190612734565b60405180910390f35b61034d60048036038101906103489190612274565b6116a2565b60405161035d949392919061274f565b60405180910390f35b610380600480360381019061037b91906123c4565b6119aa565b60405161038d9190612259565b60405180910390f35b6103b060048036038101906103ab91906123c4565b611af3565b6040516103bd9190612259565b60405180910390f35b6103e060048036038101906103db91906123c4565b611c7c565b6040516103ed9190612259565b60405180910390f35b610410600480360381019061040b9190612274565b611e00565b60405161041e929190612394565b60405180910390f35b60006001888860405161043b9291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104a457600080fd5b60006104b1898985611fa1565b1561055c57848460018d8d6040516104ca9291906127e8565b9081526020016040518091039020600b0189896040516104eb9291906127e8565b90815260200160405180910390206000019182610509929190612a47565b504260018c8c60405161051d9291906127e8565b9081526020016040518091039020600b01888860405161053e9291906127e8565b90815260200160405180910390206001018190555060019050610561565b600090505b809150509998505050505050505050565b60606000600184846040516105889291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105f157600080fd5b600186866040516106039291906127e8565b9081526020016040518091039020600c0184846040516106249291906127e8565b9081526020016040518091039020600001600187876040516106479291906127e8565b9081526020016040518091039020600c0185856040516106689291906127e8565b9081526020016040518091039020600101548180546106869061286a565b80601f01602080910402602001604051908101604052809291908181526020018280546106b29061286a565b80156106ff5780601f106106d4576101008083540402835291602001916106ff565b820191906000526020600020905b8154815290600101906020018083116106e257829003601f168201915b505050505091509150915094509492505050565b6000600186866040516107279291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461079057600080fd5b600061079d878785611fa1565b1561084857848460018b8b6040516107b69291906127e8565b9081526020016040518091039020600d0189896040516107d79291906127e8565b908152602001604051809103902060000191826107f5929190612a47565b504260018a8a6040516108099291906127e8565b9081526020016040518091039020600d01888860405161082a9291906127e8565b9081526020016040518091039020600101819055506001905061084d565b600090505b80915050979650505050505050565b6060600185856040516108709291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108d957600080fd5b600183836040516108eb9291906127e8565b908152602001604051809103902060030180546109079061286a565b80601f01602080910402602001604051908101604052809291908181526020018280546109339061286a565b80156109805780601f1061095557610100808354040283529160200191610980565b820191906000526020600020905b81548152906001019060200180831161096357829003601f168201915b50505050509050949350505050565b60606000600186866040516109a59291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a0e57600080fd5b60018686604051610a209291906127e8565b9081526020016040518091039020600b018484604051610a419291906127e8565b908152602001604051809103902060000160018787604051610a649291906127e8565b9081526020016040518091039020600b018585604051610a859291906127e8565b908152602001604051809103902060010154818054610aa39061286a565b80601f0160208091040260200160405190810160405280929190818152602001828054610acf9061286a565b8015610b1c5780601f10610af157610100808354040283529160200191610b1c565b820191906000526020600020905b815481529060010190602001808311610aff57829003601f168201915b505050505091509150915094509492505050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b8857600080fd5b8860018989604051610b9b9291906127e8565b908152602001604051809103902060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550878760018a8a604051610bfe9291906127e8565b90815260200160405180910390206001019182610c1c929190612a47565b50858560018a8a604051610c319291906127e8565b90815260200160405180910390206003019182610c4f929190612a47565b50838360018a8a604051610c649291906127e8565b90815260200160405180910390206002019182610c82929190612a47565b50818160018a8a604051610c979291906127e8565b90815260200160405180910390206004019182610cb5929190612a47565b50424443604051602001610ccb93929190612b38565b6040516020818303038152906040528051906020012060001c60018989604051610cf69291906127e8565b9081526020016040518091039020600601819055504260018989604051610d1e9291906127e8565b908152602001604051809103902060070181905550600060018989604051610d479291906127e8565b908152602001604051809103902060050160006101000a81548160ff021916908315150217905550505050505050505050565b6060600060018686604051610d909291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610df957600080fd5b60018686604051610e0b9291906127e8565b90815260200160405180910390206009018484604051610e2c9291906127e8565b908152602001604051809103902060000160018787604051610e4f9291906127e8565b90815260200160405180910390206009018585604051610e709291906127e8565b908152602001604051809103902060010154818054610e8e9061286a565b80601f0160208091040260200160405190810160405280929190818152602001828054610eba9061286a565b8015610f075780601f10610edc57610100808354040283529160200191610f07565b820191906000526020600020905b815481529060010190602001808311610eea57829003601f168201915b505050505091509150915094509492505050565b600060608060608060018787604051610f359291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1660018888604051610f799291906127e8565b908152602001604051809103902060010160018989604051610f9c9291906127e8565b908152602001604051809103902060030160018a8a604051610fbf9291906127e8565b908152602001604051809103902060020160018b8b604051610fe29291906127e8565b9081526020016040518091039020600401838054610fff9061286a565b80601f016020809104026020016040519081016040528092919081815260200182805461102b9061286a565b80156110785780601f1061104d57610100808354040283529160200191611078565b820191906000526020600020905b81548152906001019060200180831161105b57829003601f168201915b5050505050935082805461108b9061286a565b80601f01602080910402602001604051908101604052809291908181526020018280546110b79061286a565b80156111045780601f106110d957610100808354040283529160200191611104565b820191906000526020600020905b8154815290600101906020018083116110e757829003601f168201915b505050505092508180546111179061286a565b80601f01602080910402602001604051908101604052809291908181526020018280546111439061286a565b80156111905780601f1061116557610100808354040283529160200191611190565b820191906000526020600020905b81548152906001019060200180831161117357829003601f168201915b505050505091508080546111a39061286a565b80601f01602080910402602001604051908101604052809291908181526020018280546111cf9061286a565b801561121c5780601f106111f15761010080835404028352916020019161121c565b820191906000526020600020905b8154815290600101906020018083116111ff57829003601f168201915b50505050509050945094509450945094509295509295909350565b6060600060606001858560405161124f9291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146112b857600080fd5b600187876040516112ca9291906127e8565b9081526020016040518091039020600a0185856040516112eb9291906127e8565b90815260200160405180910390206000016001888860405161130e9291906127e8565b9081526020016040518091039020600a01868660405161132f9291906127e8565b908152602001604051809103902060010154600187876040516113539291906127e8565b90815260200160405180910390206003018280546113709061286a565b80601f016020809104026020016040519081016040528092919081815260200182805461139c9061286a565b80156113e95780601f106113be576101008083540402835291602001916113e9565b820191906000526020600020905b8154815290600101906020018083116113cc57829003601f168201915b505050505092508080546113fc9061286a565b80601f01602080910402602001604051908101604052809291908181526020018280546114289061286a565b80156114755780601f1061144a57610100808354040283529160200191611475565b820191906000526020600020905b81548152906001019060200180831161145857829003601f168201915b505050505090509250925092509450945094915050565b6000600188886040516114a09291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461150957600080fd5b6000611516898985611fa1565b156115c157848460018b8b60405161152f9291906127e8565b908152602001604051809103902060080189896040516115509291906127e8565b9081526020016040518091039020600001918261156e929190612a47565b504260018a8a6040516115829291906127e8565b908152602001604051809103902060080188886040516115a39291906127e8565b908152602001604051809103902060010181905550600190506115c6565b600090505b80915050979650505050505050565b6000600183836040516115e99291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461165257600080fd5b600183836040516116649291906127e8565b908152602001604051809103902060060154905092915050565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60606000606080600186866040516116bb9291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461172457600080fd5b600188886040516117369291906127e8565b908152602001604051809103902060080186866040516117579291906127e8565b90815260200160405180910390206000016001898960405161177a9291906127e8565b9081526020016040518091039020600801878760405161179b9291906127e8565b90815260200160405180910390206001015460018a8a6040516117bf9291906127e8565b9081526020016040518091039020600301600189896040516117e29291906127e8565b90815260200160405180910390206003018380546117ff9061286a565b80601f016020809104026020016040519081016040528092919081815260200182805461182b9061286a565b80156118785780601f1061184d57610100808354040283529160200191611878565b820191906000526020600020905b81548152906001019060200180831161185b57829003601f168201915b5050505050935081805461188b9061286a565b80601f01602080910402602001604051908101604052809291908181526020018280546118b79061286a565b80156119045780601f106118d957610100808354040283529160200191611904565b820191906000526020600020905b8154815290600101906020018083116118e757829003601f168201915b505050505091508080546119179061286a565b80601f01602080910402602001604051908101604052809291908181526020018280546119439061286a565b80156119905780601f1061196557610100808354040283529160200191611990565b820191906000526020600020905b81548152906001019060200180831161197357829003601f168201915b505050505090509350935093509350945094509450949050565b6000600188886040516119be9291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611a2757600080fd5b6000611a34898985611fa1565b15611adf57848460018b8b604051611a4d9291906127e8565b9081526020016040518091039020600c018989604051611a6e9291906127e8565b90815260200160405180910390206000019182611a8c929190612a47565b504260018a8a604051611aa09291906127e8565b9081526020016040518091039020600c018888604051611ac19291906127e8565b90815260200160405180910390206001018190555060019050611ae4565b600090505b80915050979650505050505050565b600060018888604051611b079291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148015611ba757506001151560018989604051611b849291906127e8565b908152602001604051809103902060050160009054906101000a900460ff161515145b611bb057600080fd5b6000611bbd898985611fa1565b15611c6857848460018b8b604051611bd69291906127e8565b9081526020016040518091039020600a018989604051611bf79291906127e8565b90815260200160405180910390206000019182611c15929190612a47565b504260018a8a604051611c299291906127e8565b9081526020016040518091039020600a018888604051611c4a9291906127e8565b90815260200160405180910390206001018190555060019050611c6d565b600090505b80915050979650505050505050565b600060018686604051611c909291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611cf957600080fd5b6000611d06878785611fa1565b15611dec57848460018b8b604051611d1f9291906127e8565b90815260200160405180910390206009018989604051611d409291906127e8565b90815260200160405180910390206000019182611d5e929190612a47565b504260018a8a604051611d729291906127e8565b90815260200160405180910390206009018888604051611d939291906127e8565b9081526020016040518091039020600101819055506001808a8a604051611dbb9291906127e8565b908152602001604051809103902060050160006101000a81548160ff02191690831515021790555060019050611df1565b600090505b80915050979650505050505050565b6060600060018686604051611e169291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611e7f57600080fd5b60018686604051611e919291906127e8565b9081526020016040518091039020600d018484604051611eb29291906127e8565b908152602001604051809103902060000160018787604051611ed59291906127e8565b9081526020016040518091039020600d018585604051611ef69291906127e8565b908152602001604051809103902060010154818054611f149061286a565b80601f0160208091040260200160405190810160405280929190818152602001828054611f409061286a565b8015611f8d5780601f10611f6257610100808354040283529160200191611f8d565b820191906000526020600020905b815481529060010190602001808311611f7057829003601f168201915b505050505091509150915094509492505050565b600060018484604051611fb59291906127e8565b908152602001604051809103902060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461201e57600080fd5b600082600186866040516120339291906127e8565b908152602001604051809103902060060154036120535760019050612058565b600090505b600180868660405161206b9291906127e8565b9081526020016040518091039020600601600082825461208b9190612ba4565b92505081905550809150509392505050565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b60008083601f8401126120cc576120cb6120a7565b5b8235905067ffffffffffffffff8111156120e9576120e86120ac565b5b602083019150836001820283011115612105576121046120b1565b5b9250929050565b6000819050919050565b61211f8161210c565b811461212a57600080fd5b50565b60008135905061213c81612116565b92915050565b600080600080600080600080600060a08a8c0312156121645761216361209d565b5b60008a013567ffffffffffffffff811115612182576121816120a2565b5b61218e8c828d016120b6565b995099505060208a013567ffffffffffffffff8111156121b1576121b06120a2565b5b6121bd8c828d016120b6565b975097505060408a013567ffffffffffffffff8111156121e0576121df6120a2565b5b6121ec8c828d016120b6565b955095505060608a013567ffffffffffffffff81111561220f5761220e6120a2565b5b61221b8c828d016120b6565b9350935050608061222e8c828d0161212d565b9150509295985092959850929598565b60008115159050919050565b6122538161223e565b82525050565b600060208201905061226e600083018461224a565b92915050565b6000806000806040858703121561228e5761228d61209d565b5b600085013567ffffffffffffffff8111156122ac576122ab6120a2565b5b6122b8878288016120b6565b9450945050602085013567ffffffffffffffff8111156122db576122da6120a2565b5b6122e7878288016120b6565b925092505092959194509250565b600081519050919050565b600082825260208201905092915050565b60005b8381101561232f578082015181840152602081019050612314565b60008484015250505050565b6000601f19601f8301169050919050565b6000612357826122f5565b6123618185612300565b9350612371818560208601612311565b61237a8161233b565b840191505092915050565b61238e8161210c565b82525050565b600060408201905081810360008301526123ae818561234c565b90506123bd6020830184612385565b9392505050565b60008060008060008060006080888a0312156123e3576123e261209d565b5b600088013567ffffffffffffffff811115612401576124006120a2565b5b61240d8a828b016120b6565b9750975050602088013567ffffffffffffffff8111156124305761242f6120a2565b5b61243c8a828b016120b6565b9550955050604088013567ffffffffffffffff81111561245f5761245e6120a2565b5b61246b8a828b016120b6565b9350935050606061247e8a828b0161212d565b91505092959891949750929550565b600060208201905081810360008301526124a7818461234c565b905092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006124da826124af565b9050919050565b6124ea816124cf565b81146124f557600080fd5b50565b600081359050612507816124e1565b92915050565b600080600080600080600080600060a08a8c03121561252f5761252e61209d565b5b600061253d8c828d016124f8565b99505060208a013567ffffffffffffffff81111561255e5761255d6120a2565b5b61256a8c828d016120b6565b985098505060408a013567ffffffffffffffff81111561258d5761258c6120a2565b5b6125998c828d016120b6565b965096505060608a013567ffffffffffffffff8111156125bc576125bb6120a2565b5b6125c88c828d016120b6565b945094505060808a013567ffffffffffffffff8111156125eb576125ea6120a2565b5b6125f78c828d016120b6565b92509250509295985092959850929598565b600080602083850312156126205761261f61209d565b5b600083013567ffffffffffffffff81111561263e5761263d6120a2565b5b61264a858286016120b6565b92509250509250929050565b61265f816124cf565b82525050565b600060a08201905061267a6000830188612656565b818103602083015261268c818761234c565b905081810360408301526126a0818661234c565b905081810360608301526126b4818561234c565b905081810360808301526126c8818461234c565b90509695505050505050565b600060608201905081810360008301526126ee818661234c565b90506126fd6020830185612385565b818103604083015261270f818461234c565b9050949350505050565b600060208201905061272e6000830184612385565b92915050565b60006020820190506127496000830184612656565b92915050565b60006080820190508181036000830152612769818761234c565b90506127786020830186612385565b818103604083015261278a818561234c565b9050818103606083015261279e818461234c565b905095945050505050565b600081905092915050565b82818337600083830152505050565b60006127cf83856127a9565b93506127dc8385846127b4565b82840190509392505050565b60006127f58284866127c3565b91508190509392505050565b600082905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061288257607f821691505b6020821081036128955761289461283b565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026128fd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826128c0565b61290786836128c0565b95508019841693508086168417925050509392505050565b6000819050919050565b600061294461293f61293a8461210c565b61291f565b61210c565b9050919050565b6000819050919050565b61295e83612929565b61297261296a8261294b565b8484546128cd565b825550505050565b600090565b61298761297a565b612992818484612955565b505050565b5b818110156129b6576129ab60008261297f565b600181019050612998565b5050565b601f8211156129fb576129cc8161289b565b6129d5846128b0565b810160208510156129e4578190505b6129f86129f0856128b0565b830182612997565b50505b505050565b600082821c905092915050565b6000612a1e60001984600802612a00565b1980831691505092915050565b6000612a378383612a0d565b9150826002028217905092915050565b612a518383612801565b67ffffffffffffffff811115612a6a57612a6961280c565b5b612a74825461286a565b612a7f8282856129ba565b6000601f831160018114612aae5760008415612a9c578287013590505b612aa68582612a2b565b865550612b0e565b601f198416612abc8661289b565b60005b82811015612ae457848901358255600182019150602085019450602081019050612abf565b86831015612b015784890135612afd601f891682612a0d565b8355505b6001600288020188555050505b50505050505050565b6000819050919050565b612b32612b2d8261210c565b612b17565b82525050565b6000612b448286612b21565b602082019150612b548285612b21565b602082019150612b648284612b21565b602082019150819050949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612baf8261210c565b9150612bba8361210c565b9250828201905080821115612bd257612bd1612b75565b5b9291505056fea2646970667358221220f1c12841f52131c6e4cec864d55c33f00ab4ac44e0f9e211b83ce7690497f83964736f6c63430008100033 \ No newline at end of file diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/contracts/DKSM.sol b/2024-shenzhen-FinTechathon/Rebirth/src/contracts/DKSM.sol new file mode 100644 index 000000000..8d2cc003e --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/contracts/DKSM.sol @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.16; + +contract DKSM { + // 用户结构体定义 + struct User { + address user; // 用户的以太坊地址 + string ID; // 用户的唯一标识符 + string Key; // 加密密钥 + string PL; // 权限列表 + string lifetime; // 生命周期 + bool login; // 登录状态 + uint256 nonce; // 随机数,用于防止重放攻击 + uint256 timestamp; // 时间戳,用于记录注册或操作时间 + mapping(string => Packet) asreq; // 存储 AS-EX 请求的映射 + mapping(string => Packet) asrep; // 存储 AS-EX 响应的映射 + mapping(string => Packet) tgsreq; // 存储 TGS-EX 请求的映射 + mapping(string => Packet) tgsrep; // 存储 TGS-EX 响应的映射 + mapping(string => Packet) apreq; // 存储 AP-EX 请求的映射 + mapping(string => Packet) aprep; // 存储 AP-EX 响应的映射 + } + + // 数据包结构体定义,用于存储消息内容和时间戳 + struct Packet { + string content; // 消息内容 + uint256 timestamp; // 消息的时间戳 + } + + address public owner; // 合约的所有者地址 + mapping(string => User) users; // 用户ID到用户信息的映射 + + // 构造函数,设置合约所有者 + constructor() { + owner = msg.sender; + } + + // 初始化用户信息的函数,仅合约所有者可以调用 + function setup(address iUser, string calldata iID, string calldata iKey, string calldata iPL, string calldata ilifetime) external { + require(msg.sender == owner); // 检查调用者是否为合约所有者 + users[iID].user = iUser; // 设置用户地址 + users[iID].ID = iID; // 设置用户ID + users[iID].Key = iKey; // 设置用户密钥 + users[iID].PL = iPL; // 设置权限列表 + users[iID].lifetime = ilifetime;// 设置生命周期 + users[iID].nonce = uint256(keccak256(abi.encodePacked(block.timestamp, block.difficulty, block.number))); // 生成随机数nonce + users[iID].timestamp = block.timestamp; // 设置时间戳 + users[iID].login = false; // 初始化登录状态为false + } + + // 获取特定用户的nonce值,用于防止重放攻击 + function get_nonce(string calldata iID) external view returns (uint256){ + require(msg.sender == users[iID].user); // 检查调用者是否为用户本人 + return users[iID].nonce; // 返回用户的nonce + } + + // 内部函数,检查提供的nonce是否与存储的nonce匹配,并递增nonce + function check_nonce(string calldata iID, uint256 _nonce) internal returns (bool) { + require(msg.sender == users[iID].user); // 检查调用者是否为用户本人 + bool Check; + if (users[iID].nonce == _nonce) { + Check = true; // nonce匹配 + } else { + Check = false; // nonce不匹配 + } + users[iID].nonce += 1; // 匹配后递增nonce + return Check; // 返回检查结果 + } + + // 返回用户的关键信息,用于验证设置的有效性 + function getInfo(string calldata iID) external view returns (address, string memory, string memory, string memory, string memory) { + return (users[iID].user, users[iID].ID, users[iID].Key, users[iID].PL, users[iID].lifetime); + } + + // 客户端设置AS-EX请求 + function C_Set_AS_REQ(string calldata IDc, string calldata IDas, string calldata AS_REQ, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + bool Check; + if (check_nonce(IDc, _nonce)) { // 检查nonce + users[IDc].asreq[IDas].content = AS_REQ; // 存储AS-EX请求内容 + users[IDc].asreq[IDas].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 认证服务器获取AS-EX请求 + function AS_Get_AS_REQ(string calldata IDc, string calldata IDas) external view returns (string memory, uint256, string memory, string memory) { + require(msg.sender == users[IDas].user); // 检查调用者是否为认证服务器用户 + return (users[IDc].asreq[IDas].content, users[IDc].asreq[IDas].timestamp, users[IDc].Key, users[IDas].Key); // 返回AS-EX请求及相关信息 + } + + // 认证服务器设置AS-EX响应 + function AS_Set_AS_REP(string calldata IDc, string calldata IDas, string calldata AS_REP, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDas].user); // 检查调用者是否为认证服务器用户 + bool Check; + if (check_nonce(IDas, _nonce)) { // 检查nonce + users[IDc].asrep[IDas].content = AS_REP; // 存储AS-EX响应内容 + users[IDc].asrep[IDas].timestamp = block.timestamp; // 设置时间戳 + users[IDc].login = true; // 更新用户登录状态为true + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 客户端获取AS-EX响应 + function C_Get_AS_REP(string calldata IDc, string calldata IDas) external view returns (string memory, uint256) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + return (users[IDc].asrep[IDas].content, users[IDc].asrep[IDas].timestamp); // 返回AS-EX响应及时间戳 + } + + //-----------------------------TGS-EX---------------------------- + // 客户端设置TGS-EX请求 + function C_Set_TGS_REQ(string calldata IDc, string calldata IDtgs, string calldata TGS_REQ, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDc].user && users[IDc].login == true); // 检查调用者是否为已登录的客户端用户 + bool Check; + if (check_nonce(IDc, _nonce)) { // 检查nonce + users[IDc].tgsreq[IDtgs].content = TGS_REQ; // 存储TGS-EX请求内容 + users[IDc].tgsreq[IDtgs].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // TGS服务器获取TGS-EX请求 + function TGS_Get_TGS_REQ(string calldata IDc, string calldata IDtgs) external view returns (string memory, uint256, string memory) { + require(msg.sender == users[IDtgs].user); // 检查调用者是否为TGS服务器用户 + return (users[IDc].tgsreq[IDtgs].content, users[IDc].tgsreq[IDtgs].timestamp, users[IDtgs].Key); // 返回TGS-EX请求及相关信息 + } + + // TGS服务器获取服务密钥 + function TGS_Get_CKv(string calldata IDtgs, string calldata IDv) external view returns (string memory) { + require(msg.sender == users[IDtgs].user); // 检查调用者是否为TGS服务器用户 + return users[IDv].Key; // 返回服务密钥 + } + + // TGS服务器设置TGS-EX响应 + function TGS_Set_TGS_REP(string calldata IDc, string calldata IDtgs, string calldata IDv, string calldata TGS_REP, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDtgs].user); // 检查调用者是否为TGS服务器用户 + bool Check; + if (check_nonce(IDtgs, _nonce)) { // 检查nonce + users[IDc].tgsrep[IDv].content = TGS_REP; // 存储TGS-EX响应内容 + users[IDc].tgsrep[IDv].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 客户端获取TGS-EX响应 + function C_Get_TGS_REP(string calldata IDc, string calldata IDv) external view returns (string memory, uint256) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + return (users[IDc].tgsrep[IDv].content, users[IDc].tgsrep[IDv].timestamp); // 返回TGS-EX响应及时间戳 + } + + //-----------------------------AP-EX---------------------------- + // 客户端设置AP-EX请求 + function C_Set_AP_REQ(string calldata IDc, string calldata IDv, string calldata AP_REQ, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + bool Check; + if (check_nonce(IDc, _nonce)) { // 检查nonce + users[IDc].apreq[IDv].content = AP_REQ; // 存储AP-EX请求内容 + users[IDc].apreq[IDv].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 服务端获取AP-EX请求 + function S_Get_AP_REQ(string calldata IDc, string calldata IDv) external view returns (string memory, uint256) { + require(msg.sender == users[IDv].user); // 检查调用者是否为服务端用户 + return (users[IDc].apreq[IDv].content, users[IDc].apreq[IDv].timestamp); // 返回AP-EX请求及时间戳 + } + + // 服务端设置AP-EX响应 + function S_Set_AP_REP(string calldata IDc, string calldata IDv, string calldata AP_REP, uint256 _nonce) external returns (bool) { + require(msg.sender == users[IDv].user); // 检查调用者是否为服务端用户 + bool Check; + if (check_nonce(IDv, _nonce)) { // 检查nonce + users[IDc].aprep[IDv].content = AP_REP; // 存储AP-EX响应内容 + users[IDc].aprep[IDv].timestamp = block.timestamp; // 设置时间戳 + Check = true; + } else { + Check = false; + } + return Check; // 返回操作结果 + } + + // 客户端获取AP-EX响应 + function C_Get_AP_REP(string calldata IDc, string calldata IDv) external view returns (string memory, uint256) { + require(msg.sender == users[IDc].user); // 检查调用者是否为客户端用户 + return (users[IDc].aprep[IDv].content, users[IDc].aprep[IDv].timestamp); // 返回AP-EX响应及时间戳 + } +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/deploy/DSKM.go b/2024-shenzhen-FinTechathon/Rebirth/src/deploy/DSKM.go new file mode 100644 index 000000000..37835c4c7 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/deploy/DSKM.go @@ -0,0 +1,93 @@ +package deploy + +import ( + "bytes" + "context" + "crypto/ecdsa" + "fmt" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "io/ioutil" + "math/big" +) + +// DeployContract 部署DKSM合约 +func DeployDKSM(client *ethclient.Client, privateKey *ecdsa.PrivateKey) common.Address { + // 加载编译后的合约 + bytecode, err := ioutil.ReadFile("bin/DKSM.bin") + if err != nil { + fmt.Println("加载合约字节码失败:", err) + } + + abiData, err := ioutil.ReadFile("abi/DKSM.abi") + if err != nil { + fmt.Println("加载合约 ABI 失败:", err) + } + + parsedABI, err := abi.JSON(bytes.NewReader(abiData)) + if err != nil { + fmt.Println("解析合约 ABI 失败:", err) + } + + // 获取账户的nonce值 + publicKey := privateKey.Public() + publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey) + if !ok { + fmt.Println("公钥转换为 ECDSA 失败") + } + + fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA) + nonce, err := client.PendingNonceAt(context.Background(), fromAddress) + if err != nil { + fmt.Println("获取 nonce 失败:", err) + } + + // 设置交易选项 + gasPrice, err := client.SuggestGasPrice(context.Background()) + if err != nil { + fmt.Println("建议的 Gas 价格获取失败:", err) + } + + chainID, err := client.NetworkID(context.Background()) + if err != nil { + fmt.Println("获取链 ID 失败:", err) + } + + auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID) + if err != nil { + fmt.Println("创建交易签名器失败:", err) + } + + auth.Nonce = big.NewInt(int64(nonce)) + auth.Value = big.NewInt(0) // 不发送以太币 + auth.GasLimit = uint64(3000000) // 设置Gas限制 + auth.GasPrice = gasPrice + + // 部署合约 + address, tx, _, err := bind.DeployContract(auth, parsedABI, common.FromHex(string(bytecode)), client) + if err != nil { + fmt.Println("部署合约失败:", err) + } + + // 等待交易执行 + receipt, err := bind.WaitMined(context.Background(), client, tx) + if err != nil { + fmt.Println("等待交易执行失败:", err) + } + + // 根据交易状态判断成功或失败 + if receipt.Status == 1 { + fmt.Println("DKSM 部署成功") + } else { + fmt.Println("DKSM 部署失败") + } + + fmt.Printf("DKSM 合约已部署到: %s\n", address.Hex()) + fmt.Printf("交易哈希: %s\n", tx.Hash().Hex()) + + // 返回合约地址 + return address +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/deploy/EthereumUtils.go b/2024-shenzhen-FinTechathon/Rebirth/src/deploy/EthereumUtils.go new file mode 100644 index 000000000..8389347c9 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/deploy/EthereumUtils.go @@ -0,0 +1,78 @@ +package deploy + +import ( + "context" + "crypto/ecdsa" + "fmt" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "io/ioutil" + "math/big" + "strings" +) + +// Foundry 函数返回智能合约实例和 auth 对象 +func Foundry(client *ethclient.Client, privateKey *ecdsa.PrivateKey, contractAddress common.Address, abiPath string) (*bind.TransactOpts, *bind.BoundContract) { + // 加载ABI文件 + parsedABI, err := LoadABI(abiPath) + if err != nil { + fmt.Println("加载合约 ABI 失败:", err) + return nil, nil + } + + // 获取链ID + chainID, err := client.NetworkID(context.Background()) + if err != nil { + fmt.Println("获取当前链的 ID 失败:", err) + return nil, nil + } + + // 创建交易签名器 + auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainID) + if err != nil { + fmt.Println("创建交易签名器失败:", err) + return nil, nil + } + + // 获取Nonce值 + fromAddress := crypto.PubkeyToAddress(privateKey.PublicKey) + nonce, err := client.PendingNonceAt(context.Background(), fromAddress) + if err != nil { + fmt.Println("获取当前账户的交易 nonce 失败:", err) + return nil, nil + } + + // 设置交易选项 + auth.Nonce = big.NewInt(int64(nonce)) + auth.Value = big.NewInt(0) // 发送0 ETH + auth.GasLimit = uint64(10000000) // 设置Gas限制 + gasPrice, err := client.SuggestGasPrice(context.Background()) + if err != nil { + fmt.Println("获取当前交易的 gas 费用失败:", err) + return nil, nil + } + auth.GasPrice = gasPrice + + // 创建智能合约实例 + instance := bind.NewBoundContract(contractAddress, parsedABI, client, client, client) + + return auth, instance +} + +// LoadABI 加载ABI文件的辅助函数 +func LoadABI(abiPath string) (abi.ABI, error) { + abiData, err := ioutil.ReadFile(abiPath) + if err != nil { + return abi.ABI{}, err + } + + parsedABI, err := abi.JSON(strings.NewReader(string(abiData))) + if err != nil { + return abi.ABI{}, err + } + + return parsedABI, nil +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/go.mod b/2024-shenzhen-FinTechathon/Rebirth/src/go.mod new file mode 100644 index 000000000..030c59dbd --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/go.mod @@ -0,0 +1,39 @@ +module DKSM + +go 1.23.3 + +require ( + github.com/ethereum/go-ethereum v1.14.12 + github.com/fentec-project/gofe v0.0.0-20220829150550-ccc7482d20ef + golang.org/x/crypto v0.30.0 +) + +require ( + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect + github.com/fentec-project/bn256 v0.0.0-20190726093940-0d0fc8bfeed0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/holiman/uint256 v1.3.1 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/supranational/blst v0.3.13 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.28.0 // indirect + rsc.io/tmplfunc v0.0.3 // indirect +) diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/go.sum b/2024-shenzhen-FinTechathon/Rebirth/src/go.sum new file mode 100644 index 000000000..cfb1fd00a --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/go.sum @@ -0,0 +1,182 @@ +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.12 h1:8hl57x77HSUo+cXExrURjU/w1VhL+ShCTJrTwcCQSe4= +github.com/ethereum/go-ethereum v1.14.12/go.mod h1:RAC2gVMWJ6FkxSPESfbshrcKpIokgQKsVKmAuqdekDY= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= +github.com/fentec-project/bn256 v0.0.0-20190726093940-0d0fc8bfeed0 h1:mkWVpEiA+MMlWxElUXRqTVSH9eETZvqJ21NZTaDaMiI= +github.com/fentec-project/bn256 v0.0.0-20190726093940-0d0fc8bfeed0/go.mod h1:llEBqR6SDQxLj2lH10BjIYPrcoqDAFv6mhsqvHfIzlI= +github.com/fentec-project/gofe v0.0.0-20220829150550-ccc7482d20ef h1:9p5/l5zk8UkCKpK1JHna7oWjWl2xi1o0lfWw7YAmrio= +github.com/fentec-project/gofe v0.0.0-20220829150550-ccc7482d20ef/go.mod h1:L8BwMRmIIEVQK1Un7rpnuOhex40gk4Quu50C8v34QFc= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= +github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= +github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/main.go b/2024-shenzhen-FinTechathon/Rebirth/src/main.go new file mode 100644 index 000000000..bf10b522a --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/main.go @@ -0,0 +1,263 @@ +package main + +import ( + "DKSM/user" + "DKSM/utils" + "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + "log" +) + +const ( + node = "http://127.0.0.1:8545/" + KDC_id = "KDC - 3D printer" + Client_id = "Teacher-01" + Server_id = "3D printer" + + SetUP = 0 // 当您选择为 0 时,说明您准备初始化 DKSM + KDC = 1 // 当您选择为 1 时, 您的身份就是 KDC + Client = 2 // 当您选择为 2 时,您的身份就是客户端 + Server = 3 // 当您选择为 3 时,您的身份就是服务器 + + C_Set_AS_REQ = 1 // 第一步为客户端向 KDC 发送 AS_REQ + KDC_Set_AS_REP = 2 // 第二步为 KDC 接收 AS_REQ 后处理请求,向客户端发送 AS_REP + C_Set_TGS_REQ = 3 // 第三步为客户端接收 AS_REP 后处理回复信息,向 KDC 发送 TGS_REQ + KDC_Set_TGS_REP = 4 // 第四步为 KDC 接收 TGS_REQ 后处理回复信息,向客户端发送 TGS_REP + C_Set_AP_REQ = 5 // 第五步为客户端接收 TGS_REP 后处理回复信息,向服务器发送 AP_REQ + S_Set_AP_REP = 6 // 第六步为服务器接收 AP_REQ 后处理回复信息,向客户端发送 AP_REP + C_Receipt_AP_REP = 7 // 第七步为客户端接收 AP_REP 后处理回复信息,验证成功后,即可安全通讯 + + Client_Send_Message = 8 + Server_Send_Message = 9 +) + +func main() { + var choice int + var KDC_Client_TGS_ForKDC string + var KDC_Client_TGS_ForClient string + var Ksession_ForClient string + var Ksession_ForServer string + + var ctxt string + flag := true + + client_ETH, err := ethclient.Dial(node) + if err != nil { + log.Fatalf("连接到以太坊客户端失败: %v", err) + } + + for flag { + // 打印提示信息 + fmt.Println("欢迎使用 DKSM 服务协议:") + fmt.Println("0. 初始化 DSKM 服务协议并部署智能合约") + fmt.Println("1. 选择您的身份为 KDC") + fmt.Println("2. 选择您的身份为 客户端") + fmt.Println("3. 选择您的身份为 服务器") + fmt.Printf("请您输入您的选择:") + + // 等待用户输入,并将输入存储到 choice 变量中 + _, err := fmt.Scanf("%d", &choice) + if err != nil { + log.Fatalf("输入无效,请输入一个整数: %v", err) + } + + switch choice { + case SetUP: + fmt.Println("-------------------------------------") + fmt.Println("当前正在为您初始化 DKSM") + + KDC_ETH_PrivateKey, err := crypto.HexToECDSA(user.KDC_True.BlockChain_PrivateKey) // 因为做的是分布式的 KDC,所以部署合约应该是 KDC 身份才对 + if err != nil { + log.Fatalf("加载私钥失败: %v", err) + } + + DKSM := utils.Setup(user.KDC_True, user.Client_True, user.Server_True, client_ETH, KDC_ETH_PrivateKey) // 初始化并获取公钥、秘密密钥和合约地址 + utils.VerifySetup(user.KDC_True, user.Client_True, user.Server_True, DKSM, client_ETH, KDC_ETH_PrivateKey) + + fmt.Println("合约部署完成,用户信息初始化成功") + fmt.Println("-------------------------------------") + + case KDC: + fmt.Println("-------------------------------------") + fmt.Println("您当前的身份为 KDC") + KDC_ETH_PrivateKey, err := crypto.HexToECDSA(user.KDC_True.BlockChain_PrivateKey) + if err != nil { + log.Fatalf("加载私钥失败: %v", err) + } + + // 打印提示信息 + fmt.Println("KDC 工作选项:") + fmt.Println("2. KDC 对客户端发送 AS_REP") + fmt.Println("4. KDC 对客户端发送 TGS_REP") + fmt.Printf("请您输入您的选择:") + + // 等待用户输入,并将输入存储到 choice 变量中 + _, err = fmt.Scanf("%d", &choice) + if err != nil { + log.Fatalf("输入无效,请输入一个整数: %v", err) + } + + fmt.Printf("请您输入 DKSM 的合约地址:") + var address string + fmt.Scanln(&address) + // 将输入字符串转换为 common.Address 类型 + DKSM := common.HexToAddress(address) + + switch choice { + case KDC_Set_AS_REP: + utils.Receipt_AS_REQ(user.KDC_True, Client_id, DKSM, client_ETH, KDC_ETH_PrivateKey) + KDC_Client_TGS_ForKDC = utils.AS_Set_AS_REP(user.KDC_True, Client_id, DKSM, client_ETH, KDC_ETH_PrivateKey) + fmt.Println("系统已自动为 KDC 存储 KDC_Client_TGS 通行凭证到 KDC_Client_TGS_ForKDC") + + case KDC_Set_TGS_REP: + utils.Receipt_TGS_REQ(user.KDC_True, KDC_Client_TGS_ForKDC, Client_id, DKSM, client_ETH, KDC_ETH_PrivateKey) + utils.TGS_Set_TGS_REP(user.KDC_True, KDC_Client_TGS_ForKDC, Client_id, Server_id, DKSM, client_ETH, KDC_ETH_PrivateKey) + + default: + continue + } + fmt.Println("-------------------------------------") + + case Client: + fmt.Println("-------------------------------------") + fmt.Println("您当前的身份为客户端") + Client_ETH_PrivateKey, err := crypto.HexToECDSA(user.Client_True.BlockChain_PrivateKey) + if err != nil { + log.Fatalf("加载私钥失败: %v", err) + } + + // 打印提示信息 + fmt.Println("客户端工作选项:") + fmt.Println("1. 客户端对 KDC 发送 AS_REQ") + fmt.Println("3. 客户端对 KDC 发送 TGS_REQ") + fmt.Println("5. 客户端对服务器发送 AP_REQ") + fmt.Println("7. 客户端确认服务器的回复信息") + fmt.Println("8. 客户端查看或给服务器留言") + fmt.Printf("请您输入您的选择:") + + // 等待用户输入,并将输入存储到 choice 变量中 + _, err = fmt.Scanf("%d", &choice) + if err != nil { + log.Fatalf("输入无效,请输入一个整数: %v", err) + } + + switch choice { + case C_Set_AS_REQ: + fmt.Printf("请您输入 DKSM 的合约地址:") + var address string + fmt.Scanln(&address) + // 将输入字符串转换为 common.Address 类型 + DKSM := common.HexToAddress(address) + // 客户端向 KDC 发送注册信息 + utils.C_Set_AS_REQ(user.Client_True, KDC_id, DKSM, client_ETH, Client_ETH_PrivateKey) + + case C_Set_TGS_REQ: + fmt.Printf("请您输入 DKSM 的合约地址:") + var address string + fmt.Scanln(&address) + // 将输入字符串转换为 common.Address 类型 + DKSM := common.HexToAddress(address) + // 客户端接收 AS_REP信息:KDC_Client_TGS, KDC.ID, TimeStamp, TGT + ASRepContent, KDC_Client_TGS_Receieve := utils.Receipt_AS_REP(user.Client_True, KDC_id, DKSM, client_ETH, Client_ETH_PrivateKey) + KDC_Client_TGS_ForClient = KDC_Client_TGS_Receieve + fmt.Println("系统已自动为客户端存储 KDC_Client_TGS 通行凭证到 KDC_Client_TGS_ForClient") + utils.C_Set_TGS_REQ(user.Client_True, ASRepContent, KDC_id, Server_id, DKSM, client_ETH, Client_ETH_PrivateKey) + + case C_Set_AP_REQ: + fmt.Printf("请您输入 DKSM 的合约地址:") + var address string + fmt.Scanln(&address) + // 将输入字符串转换为 common.Address 类型 + DKSM := common.HexToAddress(address) + Client_Server_AESKey, ST := utils.Receipt_TGS_REP(user.Client_True, KDC_Client_TGS_ForClient, Server_id, DKSM, client_ETH, Client_ETH_PrivateKey) + Ksession := utils.C_Set_AP_REQ(user.Client_True, Server_id, Client_Server_AESKey, ST, DKSM, client_ETH, Client_ETH_PrivateKey) + Ksession_ForClient = Ksession + fmt.Println("客户端持有与服务器交互的对称密钥:", Ksession_ForClient) + + case C_Receipt_AP_REP: + fmt.Printf("请您输入 DKSM 的合约地址:") + var address string + fmt.Scanln(&address) + // 将输入字符串转换为 common.Address 类型 + DKSM := common.HexToAddress(address) + utils.Receipt_AP_REP(user.Client_True, Server_id, Ksession_ForClient, DKSM, client_ETH, Client_ETH_PrivateKey) + + case Client_Send_Message: + if ctxt == "" { + fmt.Println("当前没有信息,请您发送") + fmt.Printf("请您输入您想要发送的信息:") + _, err = fmt.Scanf("%s", &ctxt) + ctxt = utils.AES_Encrypt(Ksession_ForClient, ctxt) + fmt.Println("此时留言的信息为:", ctxt) + } else { + fmt.Println("此时留言的信息为:", ctxt) + ctxt = utils.AES_Decrypt(Ksession_ForClient, ctxt) + fmt.Println("解密后查看:", ctxt) + ctxt = "" + } + + default: + continue + } + + fmt.Println("-------------------------------------") + + case Server: + fmt.Println("-------------------------------------") + fmt.Println("您当前的身份为服务器") + Server_ETH_PrivateKey, err := crypto.HexToECDSA(user.Server_True.BlockChain_PrivateKey) + if err != nil { + log.Fatalf("加载私钥失败: %v", err) + } + + // 打印提示信息 + fmt.Println("服务器工作选项:") + fmt.Println("6. 服务器对客户端发送 AP_REP") + fmt.Println("9. 服务器查看或给客户端留言") + fmt.Printf("请您输入您的选择:") + + // 等待用户输入,并将输入存储到 choice 变量中 + _, err = fmt.Scanf("%d", &choice) + if err != nil { + log.Fatalf("输入无效,请输入一个整数: %v", err) + } + + switch choice { + case S_Set_AP_REP: + fmt.Printf("请您输入 DKSM 的合约地址:") + var address string + fmt.Scanln(&address) + // 将输入字符串转换为 common.Address 类型 + DKSM := common.HexToAddress(address) + Ksession_ForServer = utils.Receipt_AP_REQ(user.Server_True, Client_id, DKSM, client_ETH, Server_ETH_PrivateKey) + fmt.Println("服务器持有与客户端交互的对称密钥:", Ksession_ForServer) + utils.S_Set_AP_REP(user.Server_True, Client_id, Ksession_ForServer, DKSM, client_ETH, Server_ETH_PrivateKey) + + case Server_Send_Message: + if ctxt == "" { + fmt.Println("当前没有信息,请您发送") + fmt.Printf("请您输入您想要发送的信息:") + _, err = fmt.Scanf("%s", &ctxt) + ctxt = utils.AES_Encrypt(Ksession_ForClient, ctxt) + fmt.Println("此时留言的信息为:", ctxt) + } else { + fmt.Println("此时留言的信息为:", ctxt) + ctxt = utils.AES_Decrypt(Ksession_ForClient, ctxt) + fmt.Println("解密后查看:", ctxt) + ctxt = "" + } + + default: + continue + } + + fmt.Println("-------------------------------------") + + default: + fmt.Println("欢迎您再次使用 DKCM 服务协议!") + flag = false + } + } +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/test/setup_KRB.go b/2024-shenzhen-FinTechathon/Rebirth/src/test/setup_KRB.go new file mode 100644 index 000000000..4641a9274 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/test/setup_KRB.go @@ -0,0 +1,225 @@ +package test + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "fmt" + "golang.org/x/crypto/pbkdf2" + "math/big" + "time" + + "github.com/fentec-project/gofe/abe" +) + +type User struct { + Addr string + ID string + Key string + PL string + Lifetime string +} + +func Setup() { + //fmt.Println("--------------------初始化开始!---------------------") + ////startTime := time.Now() + // + //KDC := User{Addr: "", ID: "KRB_KDC@GDUT", Key: "King0fDiandongche_@2022", Lifetime: "2022-12-31"} + //Clients := []User{ + // {Addr: "", ID: "Alice_2112105116@GDUT", Key: "Shuaige_isM3@2022", Lifetime: "2022-12-31"}, + //} + //Servers := []User{ + // {Addr: "", ID: "Printer_CS_No.22@GDUT", Key: "Im_notDay1ngji@2022", Lifetime: "2022-12-31"}, + //} + // + //fmt.Println("Key Generation Begin!") + // + //_, _, _, _, kdc_key, ctxt := abe_keygen(KDC.Key) + //KDC.Key = kdc_key.String() + ////fmt.Println(KDC) + //Clients[0].Key = AESkey_gen(Clients[0].Key) + //Servers[0].Key = AESkey_gen(Servers[0].Key) + //fmt.Println("当前的所有密钥:") + //fmt.Println("KDC 密钥:", KDC.Key) + //fmt.Println("Clients[0] 密钥:", Clients[0].Key) + //fmt.Println("Servers[0] 密钥:", Servers[0].Key) + // + //fmt.Println("Key Generation End!") + //fmt.Println("--------------------------------------------------") + // + //fmt.Println("Contents Encrypt Begin!") + //Clients[0].PL, _ = encrypt_AES(Clients[0].Key, "KRB_KDC@GDUT,Printer_CS_No.22@GDUT") + //Clients[0].Key, _ = encrypt_AES(KDC.Key, Clients[0].Key) + //Servers[0].Key, _ = encrypt_AES(KDC.Key, Servers[0].Key) + //KDC.Key = string(ctxt.SymEnc) + //fmt.Println("KDC 密钥:", KDC.Key) + //fmt.Println("Contents Encrypt Over!") + + // 示例使用 + key := "0123456789abcdef0123456789abcdef" // 示例密钥,32字符十六进制 + content := "GoFE 是一个加密库,提供不同的最先进的功能加密方案实现,特别是针对线性(例如内积)和二次多项式的 FE 方案。" + + encrypted, err := encrypt_AES(key, content) + if err != nil { + fmt.Println("Error encrypting:", err) + return + } + + fmt.Println("Encrypted:", encrypted) + + decrypted, err := decryptAES(key, encrypted) + + if err != nil { + fmt.Println("Error decrypting:", err) + return + } + + fmt.Println("Decrypted:", decrypted) +} + +// decryptAES 执行AES解密 +func decryptAES(key string, ciphertext string) (string, error) { + // 将十六进制字符串密钥转换为字节数组 + keyBytes, err := hex.DecodeString(key) + if err != nil { + return "", err + } + + // 获取初始化向量(IV),使用密钥的前16字节 + iv := keyBytes[:aes.BlockSize] + + // 创建AES解密器 + block, err := aes.NewCipher(keyBytes) + if err != nil { + return "", err + } + + // Base64解码密文 + encryptBytes, err := base64.StdEncoding.DecodeString(ciphertext) + if err != nil { + return "", err + } + + // 解密 + decryptBytes := make([]byte, len(encryptBytes)) + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(decryptBytes, encryptBytes) + + // 去除PKCS7填充 + decryptedText := PKCS7Unpadding(decryptBytes) + + return string(decryptedText), nil +} + +// encryptAES 执行AES加密 +func encrypt_AES(key string, content string) (string, error) { + // 将十六进制字符串密钥转换为字节数组 + keyBytes, err := hex.DecodeString(key) + if err != nil { + return "", err + } + + // 获取初始化向量(IV),使用密钥的前16字节 + iv := keyBytes[:aes.BlockSize] + + // 创建AES加密器 + block, err := aes.NewCipher(keyBytes) + if err != nil { + return "", err + } + + // 使用CBC模式 + ciphertext := make([]byte, len(PKCS7Padding(content))) + mode := cipher.NewCBCEncrypter(block, iv) + + // 对明文进行PKCS7填充后加密 + mode.CryptBlocks(ciphertext, []byte(PKCS7Padding(content))) + + // 返回Base64编码的加密结果 + return base64.StdEncoding.EncodeToString(ciphertext), nil +} + +// PKCS7Unpadding 去除PKCS7填充 +func PKCS7Unpadding(text []byte) []byte { + padding := int(text[len(text)-1]) + return text[:len(text)-padding] +} + +// PKCS7Padding 添加填充 +func PKCS7Padding(text string) string { + bs := 16 + padding := bs - len(text)%bs + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return text + string(padtext) +} + +// AESkey_gen 生成 AES 加密密钥 +func AESkey_gen(seed string) string { + // 固定的盐值 + salt := []byte{0x75, 0xea, 0x96, 0x05, 0xbc, 0x0f, 0x2e, 0x27} + // 使用 PBKDF2 生成 256 位(32 字节)的密钥 + key := pbkdf2.Key([]byte(seed), salt, 1000, 32, sha256.New) + // 将密钥转换为十六进制字符串 + return hex.EncodeToString(key) +} + +/* +ABEKeygen 的返回结果: +公钥 (pk):公钥结合特定的访问策略(如 (GDUT AND COMPUTER) AND (TEACHER OR STUDENT))来加密消息。只有属性集合满足该策略的用户才能解密密文。 +主密钥 (sk):在生成属性密钥时,主密钥与用户的属性集合一起使用,生成特定用户的解密密钥。 +属性密钥 (attribKeys):当用户尝试解密密文时,属性密钥会与密文中的加密策略进行匹配。如果匹配成功,用户就能解密数据。 +KDC 密钥 (kdcKey):kdcKey 可以作为对称加密的密钥,用于对敏感数据进行额外的加密。 +密文 (cipher):只有符合条件的用户才能解密和读取原始消息。 +*/ +func abe_keygen(seed string) (*abe.FAME, *abe.FAMEPubKey, *abe.FAMESecKey, *abe.FAMEAttribKeys, *big.Int, *abe.FAMECipher) { + // 初始化 FAME 方案 + fame := abe.NewFAME() + + // 生成主密钥对 + pk, sk, err := fame.GenerateMasterKeys() + if err != nil { + panic(fmt.Sprintf("error generating master keys: %v", err)) + } + + // 定义用户的属性集合 + attributes := []string{"COMPUTER", "STUDENT", "TEACHER", "GDUT"} + + // 为用户生成属性密钥 + attribKeys, err := fame.GenerateAttribKeys(attributes, sk) + if err != nil { + panic(fmt.Sprintf("error generating attribute keys: %v", err)) + } + + // 生成随机消息作为加密内容 + // 在 Go 中,我们使用大整数 (big.Int) 来表示消息 + // 使用字符串 seed 生成一个大整数消息 + hash := sha256.Sum256([]byte(seed)) + msg := new(big.Int).SetBytes(hash[:]) // 使用 seed 的 SHA-256 哈希值作为消息 + + fmt.Println("msg:", msg) + + // 直接使用消息作为 KDC 密钥 + kdcKey := msg + + // 定义访问策略 + msp, err := abe.BooleanToMSP("((GDUT AND COMPUTER) AND (TEACHER OR STUDENT))", false) + if err != nil { + panic(fmt.Sprintf("error converting boolean to MSP: %v", err)) + } + + // 开始加密 + startTime := time.Now() + cipher, err := fame.Encrypt(msg.String(), msp, pk) + if err != nil { + panic(fmt.Sprintf("error encrypting message: %v", err)) + } + endTime := time.Now() + + fmt.Printf("Encryption completed in %v\n", endTime.Sub(startTime)) + + // 返回公钥、主密钥、属性密钥、KDC 密钥和密文 + return fame, pk, sk, attribKeys, kdcKey, cipher +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/user/Client.go b/2024-shenzhen-FinTechathon/Rebirth/src/user/Client.go new file mode 100644 index 000000000..76a00245f --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/user/Client.go @@ -0,0 +1,10 @@ +package user + +var Client_Attribute = []string{PROFESSION_1, OFFICE_1, RESEARCHIN_1} + +var Client_True = User_True{ + ID: "Teacher-01", + Password: "Teacher's Password", + BlockChain_PrivateKey: "5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a", + Addr: "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/user/KDC.go b/2024-shenzhen-FinTechathon/Rebirth/src/user/KDC.go new file mode 100644 index 000000000..e0db036c8 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/user/KDC.go @@ -0,0 +1,10 @@ +package user + +const KDC_PL = "((Teacher OR Student) AND 310 AND (Block-Chain OR Federated-Learning))" + +var KDC_True = User_True{ + ID: "KDC - 3D printer", + Password: "KDC's Password", + BlockChain_PrivateKey: "ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", + Addr: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/user/Server.go b/2024-shenzhen-FinTechathon/Rebirth/src/user/Server.go new file mode 100644 index 000000000..5979c5a97 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/user/Server.go @@ -0,0 +1,8 @@ +package user + +var Server_True = User_True{ + ID: "3D printer", + Password: "Server's Password", + BlockChain_PrivateKey: "59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d", + Addr: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/user/user.go b/2024-shenzhen-FinTechathon/Rebirth/src/user/user.go new file mode 100644 index 000000000..17f01b9dd --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/user/user.go @@ -0,0 +1,27 @@ +package user + +type User_True struct { + ID string // 用户 ID + Password string // 用户自己的密码 + BlockChain_PrivateKey string // 设置以太坊私钥 + Addr string // 以太坊公钥地址 +} + +type User struct { + ID string // 用户 ID + Key string // 加密的 AES 密钥 + Addr string // 以太坊公钥地址 + PL string // 加密的权限列表(给 KDC 设置有什么身份的客户端能使用) + Attribute []string // 属性列表(赋予客户端对应的属性身份) +} + +const ( + PROFESSION_1 = "Teacher" + PROFESSION_2 = "Student" + + OFFICE_1 = "310" + OFFICE_2 = "223" + + RESEARCHIN_1 = "Block-Chain" + RESEARCHIN_2 = "Federated-Learning" +) diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/utils/AES.go b/2024-shenzhen-FinTechathon/Rebirth/src/utils/AES.go new file mode 100644 index 000000000..f8f1a21b7 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/utils/AES.go @@ -0,0 +1,103 @@ +package utils + +import ( + "bytes" + "crypto/aes" + "crypto/cipher" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "fmt" + "golang.org/x/crypto/pbkdf2" +) + +// AES_Key_Generate 通过用户的密码生成 AES 加密密钥 +func AES_Key_Generate(Password string) string { + // 固定的盐值 + salt := []byte{0x75, 0xea, 0x96, 0x05, 0xbc, 0x0f, 0x2e, 0x27} + // 使用 PBKDF2 生成 256 位(32 字节)的密钥 + key := pbkdf2.Key([]byte(Password), salt, 1000, 32, sha256.New) + // 将密钥转换为十六进制字符串 + return hex.EncodeToString(key) +} + +// AES_Decrypt 执行AES解密 +func AES_Decrypt(key string, ciphertext string) string { + // 将十六进制字符串密钥转换为字节数组 + keyBytes, err := hex.DecodeString(key) + if err != nil { + fmt.Println("AES 密钥转换失败:", err) + return "" + } + + // 获取初始化向量(IV),使用密钥的前16字节 + iv := keyBytes[:aes.BlockSize] + + // 创建AES解密器 + block, err := aes.NewCipher(keyBytes) + if err != nil { + fmt.Println("AES 解密器创建失败:", err) + return "" + } + + // Base64解码密文 + encryptBytes, err := base64.StdEncoding.DecodeString(ciphertext) + if err != nil { + fmt.Println("Base 64 解密失败:", err) + return "" + } + + // 解密 + decryptBytes := make([]byte, len(encryptBytes)) + mode := cipher.NewCBCDecrypter(block, iv) + mode.CryptBlocks(decryptBytes, encryptBytes) + + // 去除PKCS7填充 + decryptedText := PKCS7Unpadding(decryptBytes) + + return string(decryptedText) +} + +// AES_Encrypt 执行AES加密 +func AES_Encrypt(key string, content string) string { + // 将十六进制字符串密钥转换为字节数组 + keyBytes, err := hex.DecodeString(key) + if err != nil { + fmt.Println("AES 密钥转换失败!") + return "" + } + + // 获取初始化向量(IV),使用密钥的前16字节 + iv := keyBytes[:aes.BlockSize] + + // 创建AES加密器 + block, err := aes.NewCipher(keyBytes) + if err != nil { + fmt.Println("AES 加密器创建失败!") + return "" + } + + // 使用CBC模式 + ciphertext := make([]byte, len(PKCS7Padding(content))) + mode := cipher.NewCBCEncrypter(block, iv) + + // 对明文进行PKCS7填充后加密 + mode.CryptBlocks(ciphertext, []byte(PKCS7Padding(content))) + + // 返回Base64编码的加密结果 + return base64.StdEncoding.EncodeToString(ciphertext) +} + +// PKCS7Unpadding 去除PKCS7填充 +func PKCS7Unpadding(text []byte) []byte { + padding := int(text[len(text)-1]) + return text[:len(text)-padding] +} + +// PKCS7Padding 添加填充 +func PKCS7Padding(text string) string { + bs := 16 + padding := bs - len(text)%bs + padtext := bytes.Repeat([]byte{byte(padding)}, padding) + return text + string(padtext) +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/utils/AP-EX.go b/2024-shenzhen-FinTechathon/Rebirth/src/utils/AP-EX.go new file mode 100644 index 000000000..677a441cd --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/utils/AP-EX.go @@ -0,0 +1,247 @@ +package utils + +import ( + "DKSM/deploy" + "DKSM/user" + "context" + "crypto/ecdsa" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "fmt" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "log" + "math/big" + "strconv" + "strings" + "time" +) + +func Receipt_AP_REP(Client user.User_True, Server_ID string, Ksession string, DKSM common.Address, + client_ETH *ethclient.Client, Client_ETH_PrivateKey *ecdsa.PrivateKey) { + fmt.Println("--------------------15. 客户端接收回复信息 AP_REP!---------------------------") + ClientAuth, instance := deploy.Foundry(client_ETH, Client_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 调用合约的 C_Get_AP_REP 方法获取 AP_REP 和时间戳 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: ClientAuth.From}, &result, "C_Get_AP_REP", Client.ID, Server_ID) + if err != nil { + log.Fatalf("Failed to get AP_REP: %v", err) + } + AP_REP := result[0].(string) + fmt.Println("客户端获取服务器发送的 AP_REP 信息:", AP_REP) + TS_aprep := result[1].(*big.Int).Int64() + + // 解密 AP_REP + packet_APREP := AES_Decrypt(Ksession, AP_REP) + fmt.Println("客户端使用自己之前生成的对称密钥解密 AP_REP 信息:", packet_APREP) + + packet_APREP_parts := strings.Split(packet_APREP, ",") + fmt.Println("客户端服务请求 AP_REP 解析成功,时间戳解析结果:", packet_APREP_parts[2]) + // 获取当前时间戳 + localtime := time.Now().Unix() + fmt.Println("区块时间戳:", TS_aprep) + fmt.Println("当前系统时间:", localtime) + // 将字符串转换为 int64 + intValue, _ := strconv.ParseInt(packet_APREP_parts[2], 10, 64) + + // 检查时间戳是否在300秒内 + if localtime-intValue < 300 { + fmt.Println("服务器发送 AP_REP 跟客户端处理时间相差 300 秒内,允许通过!") + fmt.Println("客户端与服务器成功建立连接!") + } else { + fmt.Println("发送 AP_REP 跟处理时间超过 300 秒,不允许通过!") + return + } + + // 检查 AP_REP 的内容 + if packet_APREP_parts[0] == Client.ID && packet_APREP_parts[1] == Server_ID { + fmt.Println("AP_REP 检查正确,客户端与服务器已经完成密钥交换,可以安全进行通讯了!") + } else { + fmt.Println("APREP Check False") + } +} + +func S_Set_AP_REP(Server user.User_True, Client_ID string, Ksession string, DKSM common.Address, + client_ETH *ethclient.Client, Server_ETH_PrivateKey *ecdsa.PrivateKey) { + fmt.Println("--------------------14. 服务器设置回复信息 AP_REP!---------------------------") + ServerAuth, instance := deploy.Foundry(client_ETH, Server_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 调用合约的 get_nonce 方法获取 Nonce 值 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: ServerAuth.From}, &result, "get_nonce", Server.ID) + if err != nil { + log.Fatalf("Failed to get nonce for server %s: %v", Server.ID, err) + } + nonce := result[0].(*big.Int) // 将结果转换为*big.Int + + // 获取当前时间戳 + TimeStamp := time.Now().Unix() + fmt.Printf("服务器截取当前系统的时间戳:%d\n", TimeStamp) + + // 构建 AP_REP 数据包 + packet_APREP := fmt.Sprintf("%s,%s,%d", Client_ID, Server.ID, TimeStamp) + fmt.Println("服务器打包 AP_REP 信息(Client_ID,Server_ID,TimeStamp):", packet_APREP) + AP_REP := AES_Encrypt(Ksession, packet_APREP) + fmt.Println("服务器用获取到的对称密钥加密 AP_REP 后发送:", AP_REP) + + // 使用 Transact 方法调用合约的 S_Set_AP_REP 函数 + tx, err := instance.Transact(ServerAuth, "S_Set_AP_REP", Client_ID, Server.ID, AP_REP, nonce) + if err != nil { + log.Fatalf("Failed to set AP_REP: %v", err) + } + + // 等待交易执行 + receipt, err := bind.WaitMined(context.Background(), client_ETH, tx) + if err != nil { + log.Fatalf("Failed to wait for transaction mining: %v", err) + } + + // 根据交易状态判断成功或失败 + if receipt.Status == 1 { + fmt.Println("AP-REP 发送成功") + } else { + fmt.Println("AP-REP 发送失败") + } + + // 打印交易哈希 + fmt.Printf("AP-REP 已发送: %s\n", tx.Hash().Hex()) +} + +func Receipt_AP_REQ(Server user.User_True, Client_ID string, DKSM common.Address, + client_ETH *ethclient.Client, Server_ETH_PrivateKey *ecdsa.PrivateKey) string { + fmt.Println("--------------------13. 服务器接收客户端请求 AP_REQ!---------------------------") + ServerAuth, instance := deploy.Foundry(client_ETH, Server_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + // 调用合约的 S_Get_AP_REQ 方法获取 AP_REQ 和时间戳 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: ServerAuth.From}, &result, "S_Get_AP_REQ", Client_ID, Server.ID) + if err != nil { + log.Fatalf("Failed to get AP_REQ: %v", err) + } + AP_REQ := result[0].(string) + TS_apreq := result[1].(*big.Int).Int64() + + // 检查时间戳差异 + fmt.Println("服务器接收到客户端发送的 AP_REQ:", AP_REQ) + AP_REQ_Parts := strings.Split(AP_REQ, ",") + fmt.Println("客户端请求信息信息 AP_REQ 解析成功,时间戳解析结果:", AP_REQ_Parts[2]) + // 获取当前时间戳 + localtime := time.Now().Unix() + fmt.Println("区块时间戳:", TS_apreq) + fmt.Println("当前系统时间:", localtime) + intValue, _ := strconv.ParseInt(AP_REQ_Parts[2], 10, 64) + if localtime-intValue < 300 { + fmt.Println("客户端发送 AP_REQ 跟服务器处理时间相差 300 秒内,允许通过!") + + // 解密服务票据 ST + ST := AP_REQ_Parts[3] // IDc +','+ IDv +','+ Kc_v +','+ lifetime + fmt.Println("服务器取 KDC 用服务器密钥加密的 ST 密文:", ST) + packet_ST := AES_Decrypt(AES_Key_Generate(Server.Password), ST) + fmt.Println("服务器用自己的密码生成 AES 密钥解密得到 ST 明文:", packet_ST) + // 检查服务票据中的 Kc_v、IDc、IDv 是否匹配 + packet_ST_parts := strings.Split(packet_ST, ",") + if packet_ST_parts[0] == Client_ID && packet_ST_parts[1] == Server.ID { + fmt.Println("ST 内容检查通过,客户端请求服务的服务器对象正确") + } else { + fmt.Println("ST 检测失败") + return "" + } + + // 解密 Authenticator2 并验证 + KDC_Client_TGS_ForServer := packet_ST_parts[2] + fmt.Println("服务器提取 KDC 放置在 ST 中的 KDC_Client_TGS 通讯凭证:", KDC_Client_TGS_ForServer) + Authenticator2_Encrypt := AP_REQ_Parts[4] + fmt.Println("服务器提取客户端用 KDC_Client_TGS 通讯凭证加密的身份认证信息:", Authenticator2_Encrypt) + packet_Authenticator2 := AES_Decrypt(KDC_Client_TGS_ForServer, Authenticator2_Encrypt) + fmt.Println("服务器用 KDC_Client_TGS 通讯凭证解密身份验证信息:", packet_Authenticator2) + + packet_Authenticator2_parts := strings.Split(packet_Authenticator2, ",") + + // 构建 CheckSum 并验证 + packet_APREQ := strings.Join(packet_ST_parts[:3], ",") // IDc +','+ IDv +','+ ST + CheckSum_get := sha256.Sum256([]byte(packet_APREQ)) + + if packet_Authenticator2_parts[0] == Client_ID && packet_Authenticator2_parts[1] == hex.EncodeToString(CheckSum_get[:]) { + // 提取会话密钥 Ksession + Ksession := packet_Authenticator2_parts[2] + fmt.Println("客户端身份验证通过,服务器获取与客户端交互的对称密钥:", Ksession) + + return Ksession + } else { + fmt.Println("Authenticator2 Check False") + fmt.Println(packet_Authenticator2_parts[0]) + fmt.Println(Client_ID) + fmt.Println(packet_Authenticator2_parts[1]) + fmt.Println(hex.EncodeToString(CheckSum_get[:])) + fmt.Println(packet_APREQ) + return "" + } + } else { + fmt.Println("发送 AP_REQ 跟处理时间超过 300 秒,不允许通过!") + return "" + } +} + +func C_Set_AP_REQ(Client user.User_True, Server_ID string, Client_Server_AESKey string, ST string, DKSM common.Address, + client_ETH *ethclient.Client, Client_ETH_PrivateKey *ecdsa.PrivateKey) string { + fmt.Println("--------------------12. 客户端设置对服务器的请求 AP_REQ!---------------------------") + ClientAuth, instance := deploy.Foundry(client_ETH, Client_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 获取客户端的Nonce值 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: ClientAuth.From}, &result, "get_nonce", Client.ID) + if err != nil { + fmt.Println("获取", Client.ID, "的合约 nonce 失败:", err) + } + nonce := result[0].(*big.Int) // 将结果转换为*big.Int + + // 生成会话密钥 Ksession + KsessionBytes := make([]byte, 16) + _, err = rand.Read(KsessionBytes) + if err != nil { + log.Fatalf("Failed to generate Ksession: %v", err) + } + Ksession := AES_Key_Generate(hex.EncodeToString(KsessionBytes)) + fmt.Println("客户端随机生成与服务器交互的 AES 密钥 Ksession:", Ksession) + + // 获取当前时间戳 + TimeStamp := time.Now().Unix() + fmt.Printf("客户端截取当前系统的时间戳:%d\n", TimeStamp) + //lifetime := "2024-09-01" + + // 构建 AP_REQ 数据包 + packet_APREQ := fmt.Sprintf("%s,%s,%s", Client.ID, Server_ID, Client_Server_AESKey) + fmt.Println("客户端打包 AP_REQ 明文信息(Client_ID,Server_ID,Client_Server_TGS):", packet_APREQ) + CheckSum := sha256.Sum256([]byte(packet_APREQ)) + fmt.Println("客户端对 AP_REQ 明文信息做哈希计算 CheckSum:", hex.EncodeToString(CheckSum[:])) + + Authenticator2 := AES_Encrypt(Client_Server_AESKey, fmt.Sprintf("%s,%x,%s,%d", Client.ID, CheckSum, Ksession, TimeStamp)) + fmt.Println("客户端打包身份认证信息(Client.ID,CheckSum,Ksession,TimeStamp):", fmt.Sprintf("%s,%x,%s,%d", Client.ID, CheckSum, Ksession, TimeStamp)) + fmt.Println("客户端用获取到的 Client_Server_TGS 通讯凭证加密身份认证信息:", Authenticator2) + + AP_REQ := fmt.Sprintf("%s,%s,%d,%s,%s", Client.ID, Server_ID, TimeStamp, ST, Authenticator2) + fmt.Println("客户端最终发送的 AP_REQ 请求信息为:", AP_REQ) + + // 使用 Transact 方法调用合约的 C_Set_AP_REQ 函数 + tx, err := instance.Transact(ClientAuth, "C_Set_AP_REQ", Client.ID, Server_ID, AP_REQ, nonce) + if err != nil { + log.Fatalf("Failed to set AP_REQ: %v", err) + } + + // 等待交易执行 + receipt, err := bind.WaitMined(context.Background(), client_ETH, tx) + if err != nil { + log.Fatalf("Failed to wait for transaction mining: %v", err) + } + + // 根据交易状态判断成功或失败 + if receipt.Status == 1 { + fmt.Println("客户端已发送 AP-REQ:", tx.Hash().Hex()) + } else { + fmt.Println("AP-REQ 发送失败") + } + + return Ksession +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/utils/AS-EX.go b/2024-shenzhen-FinTechathon/Rebirth/src/utils/AS-EX.go new file mode 100644 index 000000000..7649e9a49 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/utils/AS-EX.go @@ -0,0 +1,261 @@ +package utils + +import ( + "DKSM/deploy" + "DKSM/user" + "context" + "crypto/ecdsa" + "crypto/rand" + "encoding/hex" + "fmt" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "log" + "math/big" + "strconv" + "strings" + "time" +) + +// Receipt_AS_REP 客户端接收 AS_REP 信息并处理 +func Receipt_AS_REP(Client user.User_True, KDC_ID string, DKSM common.Address, + client_ETH *ethclient.Client, Client_ETH_PrivateKey *ecdsa.PrivateKey) (string, string) { + fmt.Println("--------------------7. 客户端接收处理 AS_REP!---------------------------") + ClientAuth, instance := deploy.Foundry(client_ETH, Client_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 定义存储结果的切片 + var result_Client_INFO []interface{} + + // 调用合约的getInfo方法 + err := instance.Call(&bind.CallOpts{From: ClientAuth.From}, &result_Client_INFO, "getInfo", Client.ID) + if err != nil { + fmt.Println("获取", Client.ID, "信息失败:", err) + } + + // 获取用户的身份属性 + Client_Attribute_ETH := result_Client_INFO[3].(string) + fmt.Println("客户端从智能合约中获取自身的身份属性(这些属性在初始化系统时被 KDC 用客户端的 AES 密钥加密过):", Client_Attribute_ETH) + + // 切割身份属性字符串,并用自身 AES 密钥解密 + Client_AttributeList := strings.Split(Client_Attribute_ETH, ",") + Client_Key_AES := AES_Key_Generate(Client.Password) + for index, attribute := range Client_AttributeList { + Client_AttributeList[index] = AES_Decrypt(Client_Key_AES, attribute) + } + fmt.Println("客户端使用自己的密码生成 AES 密钥后解密获得自身身份属性:", Client_AttributeList[0]+","+Client_AttributeList[1]+","+Client_AttributeList[2]) + + // 调用合约的 C_Get_AS_REP 方法,获取加密的 AS_REP 和时间戳 + var result []interface{} + err = instance.Call(&bind.CallOpts{From: ClientAuth.From}, &result, "C_Get_AS_REP", Client.ID, KDC_ID) + if err != nil { + fmt.Println("客户端获取 KDC 发送的 AS_REP 失败:", err) + } + + // 解析返回结果 + AS_REP := result[0].(string) + fmt.Println("客户端接收到 KDC 发送的 AS_REP:") + fmt.Println(AS_REP) + TS_asrep := result[1].(*big.Int) + + // 解密 AS_REP + Plain_AS_REP := ABE_Decrypt(AS_REP, Client_AttributeList) + fmt.Println("客户端使用自身身份信息解密得到 AS_REP 明文信息:", Plain_AS_REP) + + Plain_AS_REP_List := strings.Split(Plain_AS_REP, ",") + + fmt.Println("KDC 回复信息 AS_REP 解析成功,客户端使用自身身份属性解密时间戳:", Plain_AS_REP_List[2]) + // 获取当前时间戳 + localtime := time.Now().Unix() + fmt.Println("区块时间戳:", TS_asrep) + fmt.Println("当前客户端处理 AS_REP 系统时间:", localtime) + intValue, _ := strconv.ParseInt(Plain_AS_REP_List[2], 10, 64) + + // 检查时间戳差异 + if localtime-intValue < 300 { + fmt.Println("KDC 发送 AS_REP 跟客户端处理时间相差 300 秒内,允许通过!") + //// 返回解密后的 AS_REP + //fmt.Printf("KDC 发送 AS_EX 回复的信息: %s\n", Plain_AS_REP) + + // 先切割出来 KDC_Client_TGS 凭证和 TGT + AS_REP_List := strings.Split(Plain_AS_REP, ",") + KDC_Client_TGS := AS_REP_List[0] + fmt.Println("客户端已接收到 KDC_Client_TGS 通行凭证(注意保存,客户端在发送 TGS_REQ 时需要使用,本系统使用了一个变量 KDC_Client_TGS_ForClient 存储):", KDC_Client_TGS) + fmt.Println("客户端已经完成跟 KDC 之间的身份认证,并完成密钥交换,之后通讯使用 KDC_Client_TGS 通讯凭证(AES 密钥)") + return Plain_AS_REP, KDC_Client_TGS + } else { + fmt.Println("发送 ASREP 跟处理时间超过 300 秒,不允许通过!") + return "", "" + } +} + +// AS_Set_AS_REP KDC 返回客户端的注册结果 +func AS_Set_AS_REP(KDC user.User_True, Client_ID string, address common.Address, + client_ETH *ethclient.Client, KDC_ETH_PrivateKey *ecdsa.PrivateKey) string { + fmt.Println("--------------------6. KDC 设置客户端注册结果信息 AS_REP!---------------------------") + KdcAuth, instance := deploy.Foundry(client_ETH, KDC_ETH_PrivateKey, address, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 获取客户端的Nonce值 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: KdcAuth.From}, &result, "get_nonce", KDC.ID) + if err != nil { + fmt.Println("获取", KDC.ID, "的合约 nonce 失败:", err) + } + nonce := result[0].(*big.Int) // 将结果转换为*big.Int + + // 生成随机的客户端通行凭证密钥 + KDC_Client_TGS_Bytes := make([]byte, 16) + _, err = rand.Read(KDC_Client_TGS_Bytes) + if err != nil { + fmt.Println("生成 KDC_Client_TGS 通行凭证失败:", err) + } + KDC_Client_TGS_Seed := hex.EncodeToString(KDC_Client_TGS_Bytes) + KDC_Client_TGS := AES_Key_Generate(KDC_Client_TGS_Seed) + fmt.Println("KDC 随机生成 KDC_Client_TGS 通行凭证(注意保存,KDC 在接收处理 TGS_REQ 时需要使用,本系统使用了一个变量 KDC_Client_TGS_ForKDC 存储):", KDC_Client_TGS) + + // 获取当前时间戳 + TimeStamp := time.Now().Unix() + fmt.Printf("KDC 截取当前系统的时间戳:%d\n", TimeStamp) + + // KDC 使用 AES 加密 TGT 信息 + TGTContent := fmt.Sprintf("%s,%s,%s", Client_ID, KDC.ID, KDC_Client_TGS) + fmt.Println("KDC 打包 TGT 明文信息(Client_ID,KDC_ID,KDC_Client_TGS):", TGTContent) + TGT := AES_Encrypt(AES_Key_Generate(KDC.Password), TGTContent) + fmt.Println("KDC 使用自己的密码生成 AES 对称加密密钥后加密 TGT 明文,密文信息:", TGT) + + // 使用 ABE 加密 AS_REP 信息,这样可以自动化验证客户端身份信息 + ASRepContent := fmt.Sprintf("%s,%s,%d,%s", KDC_Client_TGS, KDC.ID, TimeStamp, TGT) + fmt.Println("KDC 打包 AS_REP 信息(KDC_Client_TGS,KDC_ID,TimeStamp,TGT):", ASRepContent) + AS_REP := ABE_Encrypt(ASRepContent, user.KDC_PL) + fmt.Println("KDC 使用 ABE 属性基加密,访问策略为:", user.KDC_PL) + fmt.Println("KDC 最终发送的 AS_REP 回复信息为:") + fmt.Println(AS_REP) + + // 调用合约的 AS_Set_AS_REP 函数 + tx, err := instance.Transact(KdcAuth, "AS_Set_AS_REP", Client_ID, KDC.ID, AS_REP, nonce) + if err != nil { + fmt.Println("合约 AS_Set_AS_REP 无法调用:", err) + } + // 等待交易执行 + receipt, err := bind.WaitMined(context.Background(), client_ETH, tx) + if err != nil { + fmt.Println("等待交易执行失败:", err) + } + // 根据交易状态判断成功或失败 + if receipt.Status == 1 { + fmt.Println("KDC 针对客户端的 AS_REP 回复信息已发送:", tx.Hash().Hex()) + } else { + fmt.Println("KDC 的 AS_REP 设置失败") + } + + //fmt.Println(KDC.ID, "已发送注册回复信息:", tx.Hash().Hex()) + return KDC_Client_TGS +} + +/* +Receipt_AS_REQ KDC 获取客户端的注册请求 +验证是否通过后会获取到客户端发送来的 AES 密钥 +*/ +func Receipt_AS_REQ(KDC user.User_True, Client_ID string, address common.Address, + client_ETH *ethclient.Client, KDC_ETH_PrivateKey *ecdsa.PrivateKey) { + fmt.Println("--------------------5. KDC 获取 AS_REQ!---------------------------") + KdcAuth, instance := deploy.Foundry(client_ETH, KDC_ETH_PrivateKey, address, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 调用合约的 AS_Get_AS_REQ 函数 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: KdcAuth.From}, &result, "AS_Get_AS_REQ", Client_ID, KDC.ID) + if err != nil { + log.Fatalf("Failed to get AS_REQ: %v", err) + } + + // 提取返回的 AS_REQ, TS_asreq, CKc, CKas + AS_REQ := result[0].(string) // 客户端ID、KDC ID、客户端加密时间戳 + fmt.Println("KDC 接收到客户端发送的 AS_REQ:", AS_REQ) + TS_asreq := result[1].(*big.Int).Int64() // 区块时间戳 + Client_Key_AES_EncryptByKDC := result[2].(string) // 客户端被 KDC AES 加密后的密钥 + fmt.Println("KDC 获取在智能合约中存放着被 KDC AES 对称加密后的客户端的 AES 密钥:", Client_Key_AES_EncryptByKDC) + + // 提取 Kkdc 并进行 AES 解密 + KDC_Key_AES := AES_Key_Generate(KDC.Password) + Client_Key_AES := AES_Decrypt(KDC_Key_AES, Client_Key_AES_EncryptByKDC) + fmt.Println("KDC 通过自身密码生成 KDC AES 对称加密密钥后,解密得到客户端的 AES 密钥:", Client_Key_AES) + + // 从 AS_REQ 提取时间戳并解密 + ET := strings.Split(AS_REQ, ",")[2] + msg := AES_Decrypt(Client_Key_AES, ET) + if msg != "" { + fmt.Println("客户端注册请求 AS_REQ 解析成功,KDC 使用客户端的 AES 密钥解密时间戳:", msg) + // 获取当前时间戳 + localtime := time.Now().Unix() + fmt.Println("区块时间戳:", TS_asreq) + fmt.Println("当前 KDC 处理 AS_REQ 系统时间:", localtime) + // 将字符串转换为 int64 + intValue, _ := strconv.ParseInt(msg, 10, 64) + + // 检查时间戳是否在300秒内 + if localtime-intValue < 300 { + fmt.Println("客户端发送 AS_REQ 跟 KDC 处理时间相差 300 秒内,允许通过!") + } else { + fmt.Println("发送 ASREQ 跟处理时间超过 300 秒,不允许通过!") + } + } else { + fmt.Println("客户端注册请求 AS_REQ 解析失败!") + } +} + +/* + C_Set_AS_REQ + +客户端向 AS 发送注册信息,包含三段内容: +1. 客户端的 ID +2. KDC 的ID +3. ET 被客户端加密的时间戳 +*/ +func C_Set_AS_REQ(Client user.User_True, KDC_ID string, DKSM common.Address, + client_ETH *ethclient.Client, Client_ETH_PrivateKey *ecdsa.PrivateKey) { + fmt.Println("--------------------4. 客户端发送 AS_REQ!---------------------------") + ClientAuth, instance := deploy.Foundry(client_ETH, Client_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 获取客户端的Nonce值 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: ClientAuth.From}, &result, "get_nonce", Client.ID) + if err != nil { + fmt.Println("获取", Client.ID, "的合约 nonce 失败:", err) + } + nonce := result[0].(*big.Int) // 将结果转换为*big.Int + + // 获取当前时间戳 + timeStamp := time.Now().Unix() + fmt.Printf("客户端截取当前系统的时间戳:%d\n", timeStamp) + + // 生成客户端的AES密钥 + Client_key_AES := AES_Key_Generate(Client.Password) + + // 客户端 AES 加密时间戳 + ET := AES_Encrypt(Client_key_AES, fmt.Sprintf("%d", timeStamp)) + fmt.Println("客户端使用自己的密码生成 AES 对称加密密钥后加密时间戳 ET:", ET) + + // 生成 AS_REQ 消息,客户端ID、KDC ID、加密时间戳 + AS_REQ := Client.ID + "," + KDC_ID + "," + ET + fmt.Println("客户端打包 AS_REQ 发送(Client_ID,KDC_ID,ET):", AS_REQ) + + // 调用合约设置 AS_REQ + tx, err := instance.Transact(ClientAuth, "C_Set_AS_REQ", Client.ID, KDC_ID, AS_REQ, nonce) + if err != nil { + fmt.Println("合约 C_Set_AS_REQ 无法调用:", err) + } + + // 等待交易执行 + receipt, err := bind.WaitMined(context.Background(), client_ETH, tx) + if err != nil { + fmt.Println("等待交易执行失败:", err) + } + + // 根据交易状态判断成功或失败 + if receipt.Status == 1 { + //fmt.Println("Client0 的 AS_REQ 设置成功") + fmt.Println(Client.ID, "的注册信息已发送:", tx.Hash().Hex()) + } else { + fmt.Println("Client0 的 AS_REQ 设置失败") + } +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/utils/Setup.go b/2024-shenzhen-FinTechathon/Rebirth/src/utils/Setup.go new file mode 100644 index 000000000..ba911f56a --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/utils/Setup.go @@ -0,0 +1,134 @@ +package utils + +import ( + "DKSM/deploy" + "DKSM/user" + "context" + "crypto/ecdsa" + "fmt" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "strings" +) + +// Setup 初始化设置 +func Setup(KDC user.User_True, Client user.User_True, Server user.User_True, + client_ETH *ethclient.Client, KDC_ETH_PrivateKey *ecdsa.PrivateKey) common.Address { + fmt.Println("--------------------初始化开始!---------------------") + KDC_Deploy := user.User{ + ID: KDC.ID, + Key: "", + Addr: KDC.Addr, + PL: user.KDC_PL, + Attribute: nil, + } + Client_Deploy := user.User{ + ID: Client.ID, + Key: "", + Addr: Client.Addr, + PL: "", + Attribute: user.Client_Attribute, + } + Server_Deploy := user.User{ + ID: Server.ID, + Key: "", + Addr: Server.Addr, + PL: "", + Attribute: nil, + } + + KDC_Key_AES := AES_Key_Generate(KDC.Password) // 生成 KDC 的 AES 密钥 + Client_Key_AES := AES_Key_Generate(Client.Password) // 生成客户端的 AES 密钥 + Server_Key_AES := AES_Key_Generate(Server.Password) // 生成服务器的 AES 密钥 + fmt.Println("参与者的对称加密密钥如下: ") + fmt.Println("KDC_Key_AES:", KDC_Key_AES) + fmt.Println("Client_Key_AES:", Client_Key_AES) + fmt.Println("Server_Key_AES:", Server_Key_AES) + fmt.Println("------------------------------------------------") + + fmt.Println("信息加密开始!") + for index, value := range Client_Deploy.Attribute { // 客户端密钥加密自身身份 + Client_Deploy.Attribute[index] = AES_Encrypt(Client_Key_AES, value) + } + Client_Deploy.Key = AES_Encrypt(KDC_Key_AES, Client_Key_AES) // KDC 密钥加密客户端密钥 + Server_Deploy.Key = AES_Encrypt(KDC_Key_AES, Server_Key_AES) // KDC 密钥加密服务器密钥 + + fmt.Println("信息加密完成!在这里客户端的身份策略被加密,客户端密钥被加密,服务器密钥被加密。") + fmt.Println("------------------------------------------------") + + Users_Deploy := []user.User{KDC_Deploy, Client_Deploy, Server_Deploy} + + // 部署合约(Go版本的实现) + fmt.Println("--------------------1. 部署合约!---------------------------") + DKSM := deploy.DeployDKSM(client_ETH, KDC_ETH_PrivateKey) // 返回 DKSM 部署成功的合约地址 + fmt.Println("--------------------2. 设置合约用户参数!---------------------------") + for _, Value := range Users_Deploy { + KdcAuth, instance := deploy.Foundry(client_ETH, KDC_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + userAttribute := strings.Join(Value.Attribute, ",") + tx, err := instance.Transact(KdcAuth, "setup", common.HexToAddress(Value.Addr), Value.ID, Value.Key, userAttribute, "") + if err != nil { + fmt.Println("上传", Value.ID, "信息失败") + } + + // 等待交易执行 + receipt, err := bind.WaitMined(context.Background(), client_ETH, tx) + if err != nil { + fmt.Println("等待与合约交互失败:", err) + } + + // 根据交易状态判断成功或失败 + if receipt.Status == 1 { + fmt.Printf("用户 %s 设置成功\n", Value.ID) + } else { + fmt.Printf("用户 %s 设置失败\n", Value.ID) + } + } + fmt.Println("用户参数设置完成!") + + return DKSM +} + +func VerifySetup(KDC user.User_True, Client user.User_True, Server user.User_True, DKSM common.Address, + client_ETH *ethclient.Client, KDC_ETH_PrivateKey *ecdsa.PrivateKey) { + fmt.Println("--------------------3. 验证设置!---------------------------") + KdcAuth, instance := deploy.Foundry(client_ETH, KDC_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 获取用户信息的内部函数 + getInfo := func(id string) { + // 定义存储结果的切片 + var result []interface{} + + // 调用合约的getInfo方法 + err := instance.Call(&bind.CallOpts{From: KdcAuth.From}, &result, "getInfo", id) + if err != nil { + fmt.Println("获取", id, "信息失败:", err) + } + + // 提取并打印结果 + userAddress := result[0].(common.Address) + userID := result[1].(string) + userKey := result[2].(string) + userPL := result[3].(string) + userLifetime := result[4].(string) + + fmt.Printf("User Address: %s\nID: %s\nKey: %s\nPL: %s\nLifetime: %s\n", + userAddress.Hex(), + userID, + userKey, + userPL, + userLifetime) + } + + // 验证KDC信息 + fmt.Println("----------------------------- KDC 的全部信息:-----------------------------") + getInfo(KDC.ID) + + // 验证客户端信息 + fmt.Println("----------------------------- Client 的全部信息:-----------------------------") + getInfo(Client.ID) + + // 验证服务器信息 + fmt.Println("----------------------------- Server 的全部信息:-----------------------------") + getInfo(Server.ID) +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/utils/TGS-EX.go b/2024-shenzhen-FinTechathon/Rebirth/src/utils/TGS-EX.go new file mode 100644 index 000000000..1b4abae7e --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/utils/TGS-EX.go @@ -0,0 +1,262 @@ +package utils + +import ( + "DKSM/deploy" + "DKSM/user" + "context" + "crypto/ecdsa" + "crypto/rand" + "crypto/sha256" + "encoding/hex" + "fmt" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "log" + "math/big" + "strconv" + "strings" + "time" +) + +func Receipt_TGS_REP(Client user.User_True, KDC_Client_TGS_ForClient string, Server_ID string, DKSM common.Address, + client_ETH *ethclient.Client, Client_ETH_PrivateKey *ecdsa.PrivateKey) (string, string) { + fmt.Println("--------------------11. 客户端获取返回的 TGS_REP!---------------------------") + ClientAuth, instance := deploy.Foundry(client_ETH, Client_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 调用合约的 C_Get_TGS_REP 方法获取加密的 TGS_REP 和时间戳 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: ClientAuth.From}, &result, "C_Get_TGS_REP", Client.ID, Server_ID) + if err != nil { + log.Fatalf("Failed to get TGS_REP from contract: %v", err) + } + TGS_REP := result[0].(string) + fmt.Println("客户端接受到 KDC 回复的 TGS_REP:", TGS_REP) + TS_tgsrep := result[1].(*big.Int).Int64() + + // 解密 TGS_REP,解析内容 + TGS_REP_Content := AES_Decrypt(KDC_Client_TGS_ForClient, TGS_REP) + fmt.Println("客户端使用之前保存的 KDC_Client_TGS_ForClient 通行凭证解密 TGS_REP 信息:", TGS_REP_Content) + + // 解析 Kc_v 和 ST + TGS_REP_Parts := strings.Split(TGS_REP_Content, ",") + Client_Server_AESKey := TGS_REP_Parts[2] + ST := TGS_REP_Parts[3] + fmt.Println("KDC 回复信息 AS_REP 解析成功,时间戳:", TGS_REP_Parts[4]) + + // 获取当前时间戳 + localtime := time.Now().Unix() + fmt.Println("区块时间戳:", TS_tgsrep) + fmt.Println("当前系统时间:", localtime) + intValue, _ := strconv.ParseInt(TGS_REP_Parts[4], 10, 64) + + // 检查时间戳差异 + if localtime-intValue < 300 { + fmt.Println("KDC 发送 TGS_REP 跟客户端处理时间相差 300 秒内,允许通过!") + // 返回解密后的 AS_REP + fmt.Println("客户端提取 TGS_REP 中 KDC 生成的客户端跟服务器间的通讯凭证:", Client_Server_AESKey) + fmt.Println("客户端提取被 KDC 使用服务器 AES 密钥加密的 ST 密文:", ST) + return Client_Server_AESKey, ST + } else { + fmt.Println("发送 ASREP 跟处理时间超过 300 秒,不允许通过!") + return "", "" + } +} + +func TGS_Set_TGS_REP(KDC user.User_True, KDC_Client_TGS string, Client_ID string, Server_ID string, address common.Address, + client_ETH *ethclient.Client, KDC_ETH_PrivateKey *ecdsa.PrivateKey) { + fmt.Println("--------------------10. KDC 设置 TGS_REP!---------------------------") + KdcAuth, instance := deploy.Foundry(client_ETH, KDC_ETH_PrivateKey, address, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 获取客户端的Nonce值 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: KdcAuth.From}, &result, "get_nonce", KDC.ID) + if err != nil { + fmt.Println("获取", KDC.ID, "的合约 nonce 失败:", err) + } + nonce := result[0].(*big.Int) // 将结果转换为*big.Int + + // 从合约中获取 CKv + var result1 []interface{} + err = instance.Call(&bind.CallOpts{From: KdcAuth.From}, &result1, "TGS_Get_CKv", KDC.ID, Server_ID) + if err != nil { + log.Fatalf("Failed to get CKv for TGS %s and service %s: %v", KDC.ID, Server_ID, err) + } + Server_Key_AES_EncryptByKDC := result1[0].(string) + fmt.Println("KDC 获取在智能合约中存放着被 KDC AES 对称加密后的服务器的 AES 密钥:") + + // 解密 CKv 获取服务密钥 Kv + Server_Key_AES := AES_Decrypt(AES_Key_Generate(KDC.Password), Server_Key_AES_EncryptByKDC) + fmt.Println("KDC 通过自身密码生成 KDC AES 对称加密密钥后,解密得到服务器的 AES 密钥:", Server_Key_AES) + + // 生成客户端和服务之间的会话密钥 Kc_v + // 生成随机的 Kc_tgs 密钥 + Client_Server_AESKey_Bytes := make([]byte, 16) + _, err = rand.Read(Client_Server_AESKey_Bytes) + if err != nil { + fmt.Println("生成 Client_Server 通行凭证失败:", err) + } + Client_Server_AESKey_Hex := hex.EncodeToString(Client_Server_AESKey_Bytes) + Client_Server_AESKey := AES_Key_Generate(Client_Server_AESKey_Hex) + fmt.Println("KDC 随机生成客户端跟服务器间的通讯凭证 Client_Server_TGS:", Client_Server_AESKey) + + // 获取当前时间戳 + TimeStamp := time.Now().Unix() + fmt.Printf("KDC 截取当前系统的时间戳:%d\n", TimeStamp) + + // 生成加密的服务票据 ST + //lifetime := "2024-09-01" + ST := AES_Encrypt(Server_Key_AES, fmt.Sprintf("%s,%s,%s", Client_ID, Server_ID, Client_Server_AESKey)) + fmt.Println("KDC 打包 ST 明文信息(Client_ID,Server_ID,Client_Server_TGS):", fmt.Sprintf("%s,%s,%s", Client_ID, Server_ID, Client_Server_AESKey)) + fmt.Println("KDC 用服务器的 AES 密钥加密 ST,得到 ST 密文:", ST) + + // 生成加密的 TGS 响应 TGS_REP + TGS_REP := AES_Encrypt(KDC_Client_TGS, fmt.Sprintf("%s,%s,%s,%s,%d", Client_ID, Server_ID, Client_Server_AESKey, ST, TimeStamp)) + fmt.Println("KDC 打包 TGS_REP 信息(Client_ID,Server_ID,Client_Server_TGS,ST密文,TimeStamp):", fmt.Sprintf("%s,%s,%s,%s,%d", Client_ID, Server_ID, Client_Server_AESKey, ST, TimeStamp)) + fmt.Println("KDC 使用之前保存的 KDC_Client_TGS_ForKDC 通行凭证加密 TGS_REP 信息,最终发送:", TGS_REP) + + // 使用 Transact 方法调用合约的 TGS_Set_TGS_REP 函数 + tx, err := instance.Transact(KdcAuth, "TGS_Set_TGS_REP", Client_ID, KDC.ID, Server_ID, TGS_REP, nonce) + if err != nil { + log.Fatalf("Failed to set TGS_REP: %v", err) + } + + // 等待交易执行 + receipt, err := bind.WaitMined(context.Background(), client_ETH, tx) + if err != nil { + log.Fatalf("Failed to wait for transaction mining: %v", err) + } + // 根据交易状态判断成功或失败 + if receipt.Status == 1 { + fmt.Println("KDC 已发送 TGS-REP 回复信息:", tx.Hash().Hex()) + } else { + fmt.Println("KDC 发送 TGS-REP 失败") + } + + // 打印交易哈希 + fmt.Printf("TGS-REP 已发送: %s\n", tx.Hash().Hex()) +} + +func Receipt_TGS_REQ(KDC user.User_True, KDC_Client_TGS string, Client_ID string, address common.Address, + client_ETH *ethclient.Client, KDC_ETH_PrivateKey *ecdsa.PrivateKey) { + fmt.Println("--------------------9. KDC 获取 TGS_REQ!---------------------------") + KdcAuth, instance := deploy.Foundry(client_ETH, KDC_ETH_PrivateKey, address, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 调用合约的 TGS_Get_TGS_REQ 方法 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: KdcAuth.From}, &result, "TGS_Get_TGS_REQ", Client_ID, KDC.ID) + if err != nil { + log.Fatalf("Failed to get TGS_REQ from contract: %v", err) + } + + // 解析返回结果 + TGS_REQ := result[0].(string) // 数据包 + TS_tgsreq := result[1].(*big.Int).Int64() // 区块时间戳 + fmt.Println("KDC 接收到客户端发送的 TGS_REQ:", TGS_REQ) + + // 解析 TGS_REQ 内容 + TGS_REQ_Parts := strings.Split(TGS_REQ, ",") + //Client_ID = parts[0] + Server_ID := TGS_REQ_Parts[1] + fmt.Println("KDC 提取到客户端想要请求服务的服务器为:", Server_ID) + + Authenticator1_EncryptBy_KDC_Client_TGS := TGS_REQ_Parts[3] + fmt.Println("KDC 获取客户端使用 KDC_Client_TGS 通行凭证加密身份认证信息:", Authenticator1_EncryptBy_KDC_Client_TGS) + Authenticator1 := AES_Decrypt(KDC_Client_TGS, Authenticator1_EncryptBy_KDC_Client_TGS) + fmt.Println("KDC 使用先前保存的 KDC_Client_TGS_ForKDC 解密身份验证信息:", Authenticator1) + Authenticator1_Parts := strings.Split(Authenticator1, ",") + fmt.Println("客户端服务请求 TGS_REQ 解析成功,KDC 用 KDC_Client_TGS 通行凭证解密时间戳:", Authenticator1_Parts[2]) + // 获取当前时间戳 + localtime := time.Now().Unix() + fmt.Println("区块时间戳:", TS_tgsreq) + fmt.Println("当前系统时间:", localtime) + // 将字符串转换为 int64 + intValue, _ := strconv.ParseInt(Authenticator1_Parts[2], 10, 64) + + // 检查时间戳是否在300秒内 + if localtime-intValue < 300 { + fmt.Println("客户端发送 TGS_REQ 跟 KDC 处理时间相差 300 秒内,允许通过!") + // 验证 TGT_content 是否与期望值匹配 + // 解密 TGT + TGT_EncryptBy_KDC_Client_TGS := TGS_REQ_Parts[2] + fmt.Println("KDC 获取客户端使用 KDC_Client_TGS 通行凭证加密 TGT 密文:", TGT_EncryptBy_KDC_Client_TGS) + TGT := AES_Decrypt(KDC_Client_TGS, TGT_EncryptBy_KDC_Client_TGS) + fmt.Println("KDC 使用先前保存的 KDC_Client_TGS_ForKDC 解密 TGT 密文的第一层加密:", TGT) + TGT_content := AES_Decrypt(AES_Key_Generate(KDC.Password), TGT) + fmt.Println("KDC 用自己的密码生成 AES 密钥解密 TGT 密文的第二层加密:", TGT_content) + expectedValues := []string{Client_ID, KDC.ID, KDC_Client_TGS} + fmt.Println("KDC 创建验证信息(Client_ID,KDC_ID,KDC_Client_TGS):", fmt.Sprintf("%s,%s,%s", expectedValues[0], expectedValues[1], expectedValues[2])) + TGT_parts := strings.Split(TGT_content, ",") + if TGT_parts[0] == expectedValues[0] && TGT_parts[1] == expectedValues[1] && TGT_parts[2] == expectedValues[2] { + fmt.Println("KDC 验证 TGS_REQ 数据正确") + } else { + fmt.Println("TGS_REQ 解包失败") + } + } else { + fmt.Println("发送 TGS_REQ 跟处理时间超过 300 秒,不允许通过!") + } +} + +// C_Set_TGS_REQ 客户端设置 TGS-EX 请求 +func C_Set_TGS_REQ(Client user.User_True, AS_REP string, KDC_ID string, Server_ID string, DKSM common.Address, + client_ETH *ethclient.Client, Client_ETH_PrivateKey *ecdsa.PrivateKey) { + fmt.Println("--------------------8. 客户端设置 TGS_REQ!---------------------------") + ClientAuth, instance := deploy.Foundry(client_ETH, Client_ETH_PrivateKey, DKSM, "abi/DKSM.abi") // 创建签名实例和合约实例 + + // 先切割出来 KDC_Client_TGS 凭证和 TGT + AS_REP_List := strings.Split(AS_REP, ",") + KDC_Client_TGS := AS_REP_List[0] + TGT := AS_REP_List[3] + + // 获取客户端的Nonce值 + var result []interface{} + err := instance.Call(&bind.CallOpts{From: ClientAuth.From}, &result, "get_nonce", Client.ID) + if err != nil { + fmt.Println("获取", Client.ID, "的合约 nonce 失败:", err) + } + nonce := result[0].(*big.Int) // 将结果转换为*big.Int + + // 获取当前时间戳 + TimeStamp := time.Now().Unix() + fmt.Printf("客户端截取当前系统的时间戳:%d\n", TimeStamp) + + // 生成 packet_TGSREQ + fmt.Println("客户端提取 AS_REP 的第三段信息 TGT 密文(被 KDC 使用 KDC 的 AES 密钥加密过的):", TGT) + TGT_EncryptBy_KDC_Client_TGS := AES_Encrypt(KDC_Client_TGS, TGT) + fmt.Println("客户端使用 KDC_Client_TGS 通行凭证加密 TGT 密文:", TGT_EncryptBy_KDC_Client_TGS) + packet_TGSREQ := fmt.Sprintf("%s,%s,%s", Client.ID, Server_ID, TGT_EncryptBy_KDC_Client_TGS) + fmt.Println("客户端打包 TGS_REQ 信息(Client_ID,Server_ID,TGT_EncryptBy_KDC_Client_TGS):", packet_TGSREQ) + + // 计算 CheckSum + hash := sha256.New() + hash.Write([]byte(packet_TGSREQ)) + CheckSum := fmt.Sprintf("%x", hash.Sum(nil)) + fmt.Println("客户端对 TGS_REQ 做哈希计算 CheckSum:", CheckSum) + + // 生成 Authenticator1 + Authenticator1 := AES_Encrypt(KDC_Client_TGS, fmt.Sprintf("%s,%s,%d", Client.ID, CheckSum, TimeStamp)) + fmt.Println("客户端打包身份认证信息(Client_ID,CheckSum,TimeStamp):", fmt.Sprintf("%s,%s,%d", Client.ID, CheckSum, TimeStamp)) + fmt.Println("客户端使用 KDC_Client_TGS 通行凭证加密身份认证信息:", Authenticator1) + + // 生成 TGS_REQ + TGS_REQ := fmt.Sprintf("%s,%s", packet_TGSREQ, Authenticator1) + fmt.Println("客户端最终发送的 TGS_REQ 请求信息为:", TGS_REQ) + + // 使用 Transact 方法调用合约的 C_Set_TGS_REQ 函数 + tx, err := instance.Transact(ClientAuth, "C_Set_TGS_REQ", Client.ID, KDC_ID, TGS_REQ, nonce) + if err != nil { + fmt.Println("合约 C_Set_TGS_REQ 无法调用:", err) + } + + // 等待交易执行 + receipt, err := bind.WaitMined(context.Background(), client_ETH, tx) + if err != nil { + fmt.Println("等待交易执行失败:", err) + } + // 根据交易状态判断成功或失败 + if receipt.Status == 1 { + fmt.Println("客户端发送 TGS-REQ:", tx.Hash().Hex()) + } else { + fmt.Println("客户端发送 TGS-REQ 失败") + } +} diff --git a/2024-shenzhen-FinTechathon/Rebirth/src/utils/fame_ABE.go b/2024-shenzhen-FinTechathon/Rebirth/src/utils/fame_ABE.go new file mode 100644 index 000000000..4f3fd8065 --- /dev/null +++ b/2024-shenzhen-FinTechathon/Rebirth/src/utils/fame_ABE.go @@ -0,0 +1,251 @@ +package utils + +import ( + "bytes" + "compress/gzip" + "encoding/base64" + "encoding/json" + "fmt" + "github.com/fentec-project/gofe/abe" + "io/ioutil" + "strings" +) + +// bytesToSecKey 反序列化函数:将字符串反序列化为 FAMESecKey 对象 +func bytesToSecKey(data string) *abe.FAMESecKey { + // 解码 Base64 字符串 + decodedData, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return nil + } + + // 使用 gzip 解压缩 + buf := bytes.NewReader(decodedData) + zr, err := gzip.NewReader(buf) + if err != nil { + return nil + } + jsonData, err := ioutil.ReadAll(zr) + if err != nil { + return nil + } + + // 反序列化为 FAMESecKey 结构体 + var secKey abe.FAMESecKey + err = json.Unmarshal(jsonData, &secKey) + if err != nil { + fmt.Println("JSON 格式的主密钥反序列化失败:", err) + return nil + } + + return &secKey +} + +// serializeFAMESecKey 函数:序列化 FAMESecKey 对象 +func serializeFAMESecKey(secKey *abe.FAMESecKey) string { + // 将主密钥结构体序列化为 JSON 字符串 + jsonData, err := json.Marshal(secKey) + if err != nil { + fmt.Println("主密钥序列化为 JSON 失败:", err) + return "" + } + + // 使用 gzip 压缩 JSON 字符串 + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + _, err = zw.Write(jsonData) + if err != nil { + return "" + } + if err := zw.Close(); err != nil { + return "" + } + + // 将压缩后的数据编码为 Base64 字符串 + compressedEncodedData := base64.StdEncoding.EncodeToString(buf.Bytes()) + return compressedEncodedData +} + +// bytesToPubKey 反序列化函数:将字符串反序列化为 FAMEPubKey 对象 +func bytesToPubKey(data string) *abe.FAMEPubKey { + // 解码 Base64 字符串 + decodedData, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return nil + } + + // 使用 gzip 解压缩 + buf := bytes.NewReader(decodedData) + zr, err := gzip.NewReader(buf) + if err != nil { + return nil + } + jsonData, err := ioutil.ReadAll(zr) + if err != nil { + return nil + } + + // 反序列化为 FAMEPubKey 结构体 + var pubKey abe.FAMEPubKey + err = json.Unmarshal(jsonData, &pubKey) + if err != nil { + fmt.Println("JSON 格式的公钥反序列化失败:", err) + return nil + } + + return &pubKey +} + +// serializeFAMEPubKey 函数:序列化 FAMEPubKey 对象 +func serializeFAMEPubKey(pubKey *abe.FAMEPubKey) string { + // 将公钥结构体序列化为 JSON 字符串 + jsonData, err := json.Marshal(pubKey) + if err != nil { + fmt.Println("公钥序列化为 JSON 失败:", err) + return "" + } + + // 使用 gzip 压缩 JSON 字符串 + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + _, err = zw.Write(jsonData) + if err != nil { + return "" + } + if err := zw.Close(); err != nil { + return "" + } + + // 将压缩后的数据编码为 Base64 字符串 + compressedEncodedData := base64.StdEncoding.EncodeToString(buf.Bytes()) + return compressedEncodedData +} + +// bytesToCipher 反序列化函数:将字符串反序列化为 FAMECipher 对象 +func bytesToCipher(data string) *abe.FAMECipher { + // 解码 Base64 字符串 + decodedData, err := base64.StdEncoding.DecodeString(data) + if err != nil { + return nil + } + + // 使用 gzip 解压缩 + buf := bytes.NewReader(decodedData) + zr, err := gzip.NewReader(buf) + if err != nil { + return nil + } + jsonData, err := ioutil.ReadAll(zr) + if err != nil { + return nil + } + + // 反序列化为 FAMECipher 结构体 + var cipher abe.FAMECipher + err = json.Unmarshal(jsonData, &cipher) + if err != nil { + fmt.Println("JSON 格式的密文反序列化失败:", err) + return nil + } + + return &cipher +} + +// serializeFAMECipher 函数:序列化 FAMECipher 对象 +func serializeFAMECipher(cipher *abe.FAMECipher) string { + // 将结构体序列化为 JSON 字符串 + jsonData, err := json.Marshal(cipher) + if err != nil { + fmt.Println("密文序列化为 JSON 失败:", err) + return "" + } + + // 使用 gzip 压缩 JSON 字符串 + var buf bytes.Buffer + zw := gzip.NewWriter(&buf) + _, err = zw.Write(jsonData) + if err != nil { + return "" + } + if err := zw.Close(); err != nil { + return "" + } + + // 将压缩后的数据编码为 Base64 字符串 + compressedEncodedData := base64.StdEncoding.EncodeToString(buf.Bytes()) + return compressedEncodedData +} + +func ABE_Encrypt(plaintext string, policy string) string { + // 实例化 FAME 方案 + fame := abe.NewFAME() + + // 生成公钥和主密钥 + pubKey, secKey, err := fame.GenerateMasterKeys() + if err != nil { + fmt.Println("生成主密钥和公钥失败:", err) + return "" + } + + // 将策略转换为 MSP + msp, err := abe.BooleanToMSP(policy, false) + if err != nil { + fmt.Println("策略转换为 MSP 失败:", err) + return "" + } + + // 加密消息 + cipher, err := fame.Encrypt(plaintext, msp, pubKey) + if err != nil { + fmt.Println("加密失败:", err) + return "" + } + + // 序列化公钥、主密钥和密文 + serializedPubKey := serializeFAMEPubKey(pubKey) + serializedSecKey := serializeFAMESecKey(secKey) + serializedCipher := serializeFAMECipher(cipher) + + // 将序列化后的内容拼接成一个字符串,使用 "," 分隔 + finalString := fmt.Sprintf("%s,%s,%s", serializedPubKey, serializedSecKey, serializedCipher) + + return finalString +} + +func ABE_Decrypt(encryptedString string, attributes []string) string { + // 切割字符串,获取公钥、主密钥和密文的序列化字符串 + parts := strings.Split(encryptedString, ",") + if len(parts) != 3 { + fmt.Println("加密字符串格式错误") + return "" + } + + // 反序列化公钥、主密钥和密文 + pubKey := bytesToPubKey(parts[0]) + secKey := bytesToSecKey(parts[1]) + cipher := bytesToCipher(parts[2]) + + if pubKey == nil || secKey == nil || cipher == nil { + fmt.Println("反序列化失败") + return "" + } + + // 实例化 FAME 方案 + fame := abe.NewFAME() + + // 使用用户的属性生成解密密钥 + userAttribKeys, err := fame.GenerateAttribKeys(attributes, secKey) + if err != nil { + fmt.Println("生成用户属性密钥失败:", err) + return "" + } + + // 解密消息 + plaintext, err := fame.Decrypt(cipher, userAttribKeys, pubKey) + if err != nil { + fmt.Println("解密失败:", err) + return "" + } + + return plaintext +}