惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Martin Fowler
Martin Fowler
J
Java Code Geeks
博客园 - 【当耐特】
宝玉的分享
宝玉的分享
腾讯CDC
D
DataBreaches.Net
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
V
V2EX
F
Fortinet All Blogs
MyScale Blog
MyScale Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tailwind CSS Blog
Jina AI
Jina AI
GbyAI
GbyAI
大猫的无限游戏
大猫的无限游戏
A
About on SuperTechFans
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
U
Unit 42
B
Blog
M
MIT News - Artificial intelligence
N
Netflix TechBlog - Medium

博客园 - 幽州散人

SQL优化案例 synchronized 为啥会让虚拟线程卸载失效 主线任务和使命 温州3日之旅 CompletableFuture + 异步Servlet:同步的姿势、异步的效果 Snowflake雪花算法与发号器的应用 windows Java 幽灵转发壳进程 也谈MySQL limit offset深翻页问题 SHOW SESSION STATUS 与 Handler 变量 MySQL 5.7 Profiles 执行性能分析 MySQL临时表与文件排序 MySQL 5.7 MRR多范围读优化 MySQL 5.7 ICP索引条件下推优化 MySQL符合索引与最左前缀原则 从I/O 的物理成本理解回表和索引覆盖 第4个电瓶以及补漆 Flink原理:并行度与keyGroup桶 什么是数字批发银行 Java虚拟线程(三)实现原理 Java虚拟线程(二) Java虚拟线程(一) 大模型推理层服务化架构 传奇调查员之路:理智值-99,但我必须听懂深渊的语言 js里调用智能合约读/写函数的方法的区别 字节与其16进制字符表示转换的bug Redisson分布式锁 交易心得 DexScreener接口初探 某安全软件跑飞了。。 Tendermint拜占庭容错引擎
Ed25519算法签名与验签的Java实现
幽州散人 · 2026-04-02 · via 博客园 - 幽州散人

Ed25519是一种比较快速的椭圆曲线算法,区块链中有较多应用。
这里是签名和验签的Java实现,笔者用的是JDK17

package org.example;

import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class SignTest {
    public static void main(String[] args) throws Exception {
        String msg = "This is a very important message.";
        //生成密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Ed25519");
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
        String pk = Base64.getEncoder().encodeToString(publicKey.getEncoded());
        String sk = Base64.getEncoder().encodeToString(privateKey.getEncoded());
        System.out.println("Public Key:" + pk);
        System.out.println("Private Key:" + sk);

        //签名
        String signatureBase64 = sign(msg, sk);
        System.out.println("Signature:" + signatureBase64);

        //验签
        boolean success = verify(msg, signatureBase64, pk);
        System.out.println("验签结果:" + success);

        success = verify(msg + "这是加上去的篡改内容", signatureBase64, pk);
        System.out.println("验签结果:" + success);

    }

    public static String sign(String msg, String skBase64) throws Exception{
        //从base64中把PrivateKey反序列化还原回来,KeySpec用PKCS8EncodedKeySpec
        byte[] keyBytes =  Base64.getDecoder().decode(skBase64);
        KeyFactory keyFactory = KeyFactory.getInstance("Ed25519");
        PrivateKey privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));

        Signature signer = Signature.getInstance("Ed25519");
        signer.initSign(privateKey); //设置PrivateKey
        signer.update(msg.getBytes()); //设置要签名的数据
        byte[] signedBytes = signer.sign(); //生成签名
        String encodedMsg = Base64.getEncoder().encodeToString(signedBytes); //序列化编码,base64格式
        return encodedMsg;
    }

    public static boolean verify(String msg, String signatureBase64, String pkBase64) throws Exception{
        //从base64还原PublicKey, KeySpec用 X509EncodedKeySpec
        byte[] keyBytes = Base64.getDecoder().decode(pkBase64);
        KeyFactory keyFactory = KeyFactory.getInstance("Ed25519");
        PublicKey publicKey = keyFactory.generatePublic(new X509EncodedKeySpec(keyBytes));
        Signature verifier = Signature.getInstance("Ed25519");

        verifier.initVerify(publicKey);
        verifier.update(msg.getBytes());
        byte[] signedBytes = Base64.getDecoder().decode(signatureBase64);
        boolean verify = verifier.verify(signedBytes);
        return verify;
    }
}

运行结果:

Public Key:MCowBQYDK2VwAyEAXfZ3xKG0ym2kygw18irwPVkMx4rbT2MGSpS2HoQpR+E=
Private Key:MC4CAQAwBQYDK2VwBCIEIOFp7lvboCTEk4+5EiNPOimF4IL80S63P1hksaq2TFka
Signature:sRte+V0FM/d6JGT/HOm8Qp6/+S47E8Wo3jxOeuFAWF80yAjbEwaPhZvxuR2Jk4+CEbjtjxA9MoTBSZZPd9+LDA==
验签结果:true
验签结果:false