PHP解析v3版Tor洋葱地址:提取公钥、校验和与版本信息


php解析v3版tor洋葱地址:提取公钥、校验和与版本信息

本文详细阐述如何使用PHP程序化地解析v3版Tor洋葱地址。通过遵循Tor的rend-spec-v3规范,我们将深入探讨洋葱地址的结构,学习如何从Base32编码的字符串中精确提取出服务公钥、校验和以及版本号,并提供具体的PHP实现代码,以帮助开发者理解并应用这些解析技术。

理解v3洋葱地址结构

Tor的v3洋葱地址设计旨在提供更高的安全性和更强的匿名性。其核心结构是一个Base32编码的字符串,该字符串由三个关键组件拼接而成:服务身份公钥(PUBKEY)、校验和(CHECKSUM)和版本号(VERSION)。完整的洋葱地址格式为 base32(PUBKEY | CHECKSUM | VERSION) + ".onion"。

  • PUBKEY (公钥): 这是一个32字节的Ed25519主公钥,用于唯一标识隐藏服务。
  • CHECKSUM (校验和): 这是一个2字节的校验值,通过对特定常量字符串、公钥和版本号进行哈希计算并截取前两字节得到。其计算公式为 H(".onion checksum" | PUBKEY | VERSION)[:2]。
  • VERSION (版本号): 这是一个1字节的版本字段,当前v3洋葱地址的默认值为 \x03(即十进制的3)。

因此,一个Base32解码后的v3洋葱地址字符串总长度为 32 (PUBKEY) + 2 (CHECKSUM) + 1 (VERSION) = 35 字节。

PHP实现:解析v3洋葱地址

要从v3洋葱地址中提取这些组件,我们需要执行以下步骤:

Primeshot Primeshot

专业级AI人像摄影工作室

Primeshot 36 查看详情 Primeshot
  1. 移除 .onion 后缀: 首先,从完整的洋葱地址中移除末尾的 .onion 字符串,以获得纯粹的Base32编码部分。
  2. Base32解码: 对剩余的字符串进行Base32解码。解码结果将是一个35字节的二进制字符串。
  3. 提取组件: 根据v3洋葱地址的结构定义,从解码后的二进制字符串中按顺序提取公钥、校验和和版本号。

以下是一个PHP示例代码,演示了如何执行这些操作。为了进行Base32解码,我们将使用一个常见的PHP Base32库(例如 StephenHill\Base32,您需要通过Composer安装它)。

<?php

// 假设您已经通过Composer安装了StephenHill\Base32库
// require 'vendor/autoload.php';

// 如果没有使用Composer,或者想手动引入,可以参考以下简化版Base32解码函数
// 注意:以下Base32解码函数仅为示例,可能不具备生产环境的健壮性
// 推荐使用成熟的库,如 StephenHill\Base32
class Base32
{
    private static $map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';

    public static function decode(string $input): string
    {
        $input = strtoupper($input);
        $paddingChar = '=';
        if (strpos($input, $paddingChar) !== false) {
            $input = substr($input, 0, strpos($input, $paddingChar));
        }

        $bitBuffer = 0;
        $bitCount = 0;
        $output = '';

        for ($i = 0; $i < strlen($input); $i++) {
            $char = $input[$i];
            $val = strpos(self::$map, $char);

            if ($val === false) {
                // Invalid character, handle error or skip
                continue;
            }

            $bitBuffer = ($bitBuffer << 5) | $val;
            $bitCount += 5;

            while ($bitCount >= 8) {
                $bitCount -= 8;
                $output .= chr(($bitBuffer >> $bitCount) & 0xFF);
            }
        }
        return $output;
    }
}


/**
 * 解析v3 Tor洋葱地址,提取公钥、校验和与版本号。
 *
 * @param string $onionAddress 完整的v3洋葱地址,例如 "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion"
 * @return array|null 包含 'publicKey', 'checksum', 'version' 的关联数组,或解析失败返回 null
 */
function parseV3OnionAddress(string $onionAddress): ?array
{
    // 1. 移除 .onion 后缀
    if (!str_ends_with($onionAddress, '.onion')) {
        echo "错误: 无效的洋葱地址格式,缺少 '.onion' 后缀。\n";
        return null;
    }
    $base32Encoded = str_replace(".onion", "", $onionAddress);

    // 2. Base32 解码
    // 使用 StephenHill\Base32 库
    // $decodedBytes = \StephenHill\Base32::decode($base32Encoded);
    // 使用上面提供的简化版Base32类
    $decodedBytes = Base32::decode($base32Encoded);


    // v3洋葱地址解码后应为35字节
    if (strlen($decodedBytes) !== 35) {
        echo "错误: Base32解码后的长度不符合v3洋葱地址规范 (期望35字节,实际 " . strlen($decodedBytes) . " 字节)。\n";
        return null;
    }

    // 3. 提取组件
    // PUBKEY 是前32字节
    $publicKey = substr($decodedBytes, 0, 32);

    // CHECKSUM 是接下来的2字节 (即第33和34字节,0-indexed)
    $checksum = substr($decodedBytes, 32, 2);

    // VERSION 是最后1字节 (即第35字节,0-indexed)
    $version = substr($decodedBytes, 34, 1);

    return [
        'publicKey' => bin2hex($publicKey), // 通常以十六进制表示
        'checksum' => bin2hex($checksum),   // 通常以十六进制表示
        'version' => ord($version)          // 版本号通常是整数
    ];
}

// 示例使用
$onionUrl = "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion";
$parsedData = parseV3OnionAddress($onionUrl);

if ($parsedData) {
    echo "解析成功!\n";
    echo "公钥 (hex): " . $parsedData['publicKey'] . "\n";
    echo "校验和 (hex): " . $parsedData['checksum'] . "\n";
    echo "版本号: " . $parsedData['version'] . "\n";

    // 验证版本号是否为3
    if ($parsedData['version'] === 3) {
        echo "版本号符合v3规范 (3)。\n";
    } else {
        echo "警告: 版本号不为3,可能不是标准的v3洋葱地址。\n";
    }
}

// 另一个示例
$onionUrl2 = "sp3k262uwy4r2k3ycr5awluarykdpag6a7y33jxop4cs2lu5uz5sseqd.onion";
$parsedData2 = parseV3OnionAddress($onionUrl2);
if ($parsedData2) {
    echo "\n--- 第二个地址解析 ---\n";
    echo "公钥 (hex): " . $parsedData2['publicKey'] . "\n";
    echo "校验和 (hex): " . $parsedData2['checksum'] . "\n";
    echo "版本号: " . $parsedData2['version'] . "\n";
}

?>

代码解释:

  • str_ends_with() 用于检查字符串是否以特定后缀结尾,是PHP 8+ 的函数。如果使用旧版本PHP,可以替换为 substr($onionAddress, -6) === '.onion'。
  • str_replace(".onion", "", $onionAddress) 移除了后缀。
  • Base32::decode($base32Encoded) 执行Base32解码。这里为了演示,提供了一个简化的 Base32 类,但在实际生产环境中,强烈建议使用经过充分测试和维护的第三方库,例如 StephenHill\Base32。
  • substr($decodedBytes, offset, length) 函数用于从二进制字符串中提取指定长度的子字符串。
    • substr($decodedBytes, 0, 32) 提取前32字节作为公钥。
    • substr($decodedBytes, 32, 2) 提取接下来的2字节作为校验和。
    • substr($decodedBytes, 34, 1) 提取最后1字节作为版本号。
  • bin2hex() 将二进制字符串转换为十六进制表示,这在显示公钥和校验和时非常有用,因为它们通常以十六进制格式呈现。
  • ord() 将单字节字符转换为其ASCII值,对于版本号 \x03,它会返回整数 3。

注意事项与总结

  1. Base32解码库: 务必使用一个可靠且经过测试的Base32解码库。本文提供的简化版仅用于说明原理,不建议直接用于生产环境。
  2. 二进制字符串处理: PHP在处理字符串时,需要注意其是否为二进制安全。substr()、strlen() 等函数在处理二进制数据时是安全的。
  3. 校验和验证: 为了进一步验证洋葱地址的有效性,您可以根据Tor规范重新计算校验和,并与提取出的校验和进行比较。如果两者不匹配,则表明洋葱地址可能被篡改或无效。校验和的计算需要用到哈希函数(如SHA3),以及原始的公钥和版本号。
  4. 错误处理: 在实际应用中,应增加更完善的错误处理机制,例如捕获Base32解码失败、地址格式不正确等情况。

通过上述步骤和PHP代码示例,您现在应该能够程序化地解析v3版Tor洋葱地址,并从中提取出其核心组成部分。这对于开发与Tor隐藏服务相关的工具或进行数据分析非常有用。

以上就是PHP解析v3版Tor洋葱地址:提取公钥、校验和与版本信息的详细内容,更多请关注php中文网其它相关文章!


# composer  # 编码  # 字节  # 工具  # ssl  # php解析  # 公钥  # 移除  # php  # 怎么看  # 网站怎么做项目推广  # 通化网站推广费用  # 萧山seo公司排名  # 哈尔滨网站推广 溦薪hfqjwl广告稳定  # 本溪哪里有网站优化  # 潜江网站建设策划招聘  # 您可以  # 推荐使用  # 但在  # 简化版  # 常以  # 是一个  # 这是一个  # 聊城短视频seo优化  # 网站代码优化细节  # 推广优化网站收录  # 网站建设推广服务好 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: word表格如何按某一列内容进行排序_Word表格按列排序方法  高德地图怎么查看未来行程规划_高德地图未来行程规划查看方法  PointNet++语义分割模型中类别变更引发的断言错误及标签处理策略  mysql导入sql文件能分批导入吗_mysql分批次导入大sql文件的实用技巧  苹果电脑如何快速查看电池状态 苹果电脑电池信息快捷方法  《edge浏览器》关闭翻译功能方法  《顺丰同城骑士》查看我的技能方法  RxJS中如何高效地在一个函数内处理和合并多个数据集合  抖音怎么解除第三方绑定_抖音解除第三方平台绑定方法介绍  《七读免费小说》开通会员方法  excel怎么制作考勤表 excel考勤模板与函数公式讲解  Coolpad5890 ROM刷机包  J*aScript:从子元素中批量移除特定CSS类  《宝可梦大集结》S4冠军之路开始时间介绍  行者app怎样导出日志  CSS动画如何实现图标旋转并放大_transform rotate scale @keyframes实现  铁路12306入口 铁路12306官网版入口登录网址  CodeIgniter 3 连接 SQL Server:正确获取查询结果的教程  优化响应式标题底部边框:CSS实现技巧与最佳实践  MySQL多重JOIN技巧:高效关联同一表获取多角色信息  Windows 11怎么删除恢复分区_Windows 11使用Diskpart命令强行删除分区  ToDesk远程摄像头功能使用方法_ToDesk远程视频画面查看设置教程  iCloud官方网站 iCloud网页版在线登录入口  tiktok国际版入口_tiktok官网网页版链接  J*aScript深度克隆:实现高效、健壮与安全的复杂对象复制  J*aScript中高效处理用户输入:从Keyup事件到表单提交的优化实践  J*aScript文本高亮功能优化:解决多词匹配错误与精确分割策略  漫蛙官网(首页入口)_漫蛙漫画稳定访问教程分享  《360浏览器》设置摄像头权限方法  基于 Flink 和 Kafka 实现高效流处理:连续查询与时间窗口  《单词速记宝》设置学习计划方法  青橙手机语音助手怎么唤醒_青橙手机语音助手设置与唤醒方法  微信网页版在线登录 微信网页版在线使用入口  悟空浏览器网页版在线工具 悟空浏览器网页版在线平台入口  Retrofit根路径POST请求:@POST("/") 的应用与解析  Golang如何测试结构体方法_Golang reflect方法测试与调用技巧  《飞猪旅行》购买汽车票方法  163邮箱网页版入口 163邮箱在线使用  智学网成绩单查询系统网_智学网学生平台登录  Dagster资产间数据传递与用户配置管理教程  如何在CSS中使用伪类选择器_hover实现悬停效果  J*a里如何处理ArithmeticException并防止除零_算术异常防护策略解析  Flexbox布局:实现粘性导航与底部页脚的完美结合  优酷下载视频的清晰度怎么选_优酷缓存清晰度设置与选择指南  解决jQuery多计算器输入字段冲突的教程  iPhone14无法连接蓝牙设备如何解决  键盘保修需要什么_键盘售后维修流程  教育查询官方网站入口 教育个人档案查询免费官网  《kimi智能助手》制作ppt教程  《小黑盒》删除历史浏览方法 

 2025-11-19

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.