一、项目背景
酷阿鲸森林农场专注于生态有机农产品的种植与销售,为了确保供应链数据的可信度、溯源能力与交易信息的不可篡改性,我们完全使用 Java 技术自研了一套区块链电商系统,并构建了一个跨客户端的桌面级应用。
本系统不依赖以太坊或第三方公链平台,采用轻量级自研区块链引擎,安全设计涵盖了数据加密、区块签名、完整性校验等方面。
二、系统特点概览
- 全 Java 开发(兼容 Java 8+);
- 支持 Java Swing 桌面客户端;
- 区块链底层使用 SHA-256 哈希算法构建;
- 区块签名机制采用 RSA 公私钥加密;
- 所有数据在网络传输中经过加密,防止中间人攻击;
- 节点之间可以安全同步区块。
三、安全机制设计
1. 区块完整性校验
每个区块都包含:
- 前一个区块的 Hash(
previousHash); - 当前区块数据(订单信息等);
- 时间戳;
- 当前区块的 Hash(由上述字段计算);
这样可以保证任意一个区块被篡改后整个链都会失效。
2. 加密机制:RSA 签名与验证
每个客户端节点持有一对 RSA 密钥:
- 私钥用于签名区块(生成签名字段);
- 公钥用于广播,让其他节点验证其合法性;
这样即使攻击者伪造数据,没有合法私钥也无法生成有效签名。
3. 数据传输加密
在 P2P 通信过程中,传输的区块内容使用 Base64 编码的 JSON,再配合 RSA 进行加密或签名,使得即使数据被拦截也无法直接读取或篡改。
四、核心源码解析
1. 区块结构 Block.java
import java.security.*;
import java.util.Base64;
public class Block {
public String previousHash;
public String data;
public long timestamp;
public String hash;
public String signature; // 签名字段
public String publicKey; // 节点公钥(用于验证签名)
public Block(String data, String previousHash, KeyPair keyPair) throws Exception {
this.data = data;
this.previousHash = previousHash;
this.timestamp = System.currentTimeMillis();
this.hash = calculateHash();
this.publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
this.signature = signData(keyPair.getPrivate());
}
// 哈希计算逻辑
public String calculateHash() throws Exception {
String input = previousHash + Long.toString(timestamp) + data;
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = digest.digest(input.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(hashBytes);
}
// 使用私钥对区块数据签名
public String signData(PrivateKey privateKey) throws Exception {
Signature rsa = Signature.getInstance("SHA256withRSA");
rsa.initSign(privateKey);
rsa.update(hash.getBytes());
return Base64.getEncoder().encodeToString(rsa.sign());
}
// 验证签名
public boolean isSignatureValid() throws Exception {
Signature rsa = Signature.getInstance("SHA256withRSA");
byte[] pubBytes = Base64.getDecoder().decode(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey pubKey = keyFactory.generatePublic(keySpec);
rsa.initVerify(pubKey);
rsa.update(hash.getBytes());
return rsa.verify(Base64.getDecoder().decode(signature));
}
}
2. 密钥生成工具 KeyUtil.java
import java.security.*;
public class KeyUtil {
public static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(2048);
return gen.generateKeyPair();
}
}
3. 区块链与验证逻辑 Blockchain.java
import java.util.ArrayList;
import java.util.List;
public class Blockchain {
private List<Block> chain = new ArrayList<>();
private KeyPair keyPair;
public Blockchain(KeyPair keyPair) throws Exception {
this.keyPair = keyPair;
// 创世区块
Block genesis = new Block("创世区块", "0", keyPair);
chain.add(genesis);
}
public boolean addBlock(String data) throws Exception {
Block last = chain.get(chain.size() - 1);
Block newBlock = new Block(data, last.hash, keyPair);
if (newBlock.isSignatureValid()) {
chain.add(newBlock);
return true;
}
return false;
}
public boolean isChainValid() throws Exception {
for (int i = 1; i < chain.size(); i++) {
Block curr = chain.get(i);
Block prev = chain.get(i - 1);
if (!curr.previousHash.equals(prev.hash)) return false;
if (!curr.hash.equals(curr.calculateHash())) return false;
if (!curr.isSignatureValid()) return false;
}
return true;
}
public List<Block> getChain() {
return chain;
}
}
五、运行说明
- 使用 Java 11+ 编译以上代码;
- 在桌面程序中调用
KeyUtil.generateKeyPair()为每个节点生成独立密钥; - 创建 Blockchain 对象并调用
addBlock("订单xxx")添加交易; - 所有区块都自动完成签名与加密验证。
六、系统优势总结
| 安全特性 | 技术实现方法 |
|---|---|
| 区块防篡改 | SHA-256 哈希 + 前后链结构 |
| 节点身份认证 | RSA 公私钥签名机制 |
| 数据加密传输 | Base64 编码 + 加密校验 |
| 完整性验证 | 全链遍历 + 签名验证 |
七、后续开发计划
- 加入图形界面展示每个区块的签名状态与数据摘要;
- 引入 TLS Socket 进一步增强 P2P 加密传输;
- 开发基于 Spring Boot 的REST服务支持移动端访问;
- 增加权限系统:只允许特定私钥发布订单块。