Java/PHP/C ... 几种语言 RSA 的互操作

本文探讨了不同编程语言对RSA算法的支持,重点介绍了如何将OpenSSL产生的PEM格式密钥转换为DER格式,以及PHP、Java、Python等语言进行RSA加密解密的基本方法。同时,还涉及了使用RSA进行数字签名和验证的过程,并讨论了不同语言之间在哈希算法和RSA密钥封装上的差异。

 

转自:http://www.dup2.org/node/1096

最近有一个项目,涉及到和别的网站合作,双方通信的鉴权计划是通过 RSA 来做。由于可能涉及到不同的开发环境,于是要研究一下各个语言对 RSA 的支持

openssl 缺省创建出来的公密钥文件是 PEM 格式的,但 Java API 导入密码只能是 DER 格式,特别是密钥必须用 PKCS#8 编码。这就需要对 openssl 产生出来的文件做一下转换

    • openssl rsa -inform PEM -in rsapriv.pem -outform DER -pubout -out rsapub.der
    • openssl pkcs8 -topk8 -inform PEM -in rsapriv.pem -outform DER -nocrypt -out rsapriv.der
  1. 基础算法的标准是 openssl 的:RSA_private_encrypt/RSA_public_decrypt、RSA_public_encrypt/RSA_private_decrypt 这4个函数,因为 PHP 的 openssl 模块也只提供了这 4 个基础函数(不要幻想用非 openssl 模块之外的东西来做 RSA 运算,比如 PEAR 的 Crypt_RSA,速度慢到令人发指)
  2. 要注意上述 4 个函数里,可使用的 padding 参数只有那么有限的几种。对应 Java 里面 Cipher.getInstance() 的参数,只能用 "RSA/NONE/PKCS1Padding" 或 "RSA/NONE/NoPadding"(或许 "RSA/None/OAEPPadding" 是对应RSA_PKCS1_OAEP_PADDING,但我没有深究了)。缺省 PHP 里的 padding 是 RSA_PKCS1_PADDING
  3. 关于 python... 嗯,直接用 ctypes 就好啦
  4. 用 RSA 签名都是首先将文本做一个单向 hash,然后用私钥将签名加密;校验端拿到签名和文本,用公钥将签名解密,对比是否是文本的 hash。openssl 因此封装了 RSA_sign/RSA_verify 来做这个事情。

    总之为了更多语言的互操作能力,我们现在没有用 RSA_sign/RSA_verify 这两个封装好的函数。

<think>我们正在解决两个相互关联的问题: 1. 执行 `find ~ -name "*.pub" -o -name "id_*" -o -name "ssh_key*" 2>/dev/null` 无输出,但用户确认已经创建了自定义pub文件(例如 `dushan_rsa.pub`)。 2. 执行 `cat ~/.ssh/id_rsa.pub` 时提示 `No such file or directory`。 根据用户描述,自定义pub文件已创建(比如名为 `dushan_rsa.pub`),但默认的 `id_rsa.pub` 不存在。因此,我们需要: - 定位自定义公钥文件的位置。 - 使用正确的路径查看公钥内容。 - 解决 `find` 命令找不到文件的原因。 可能的原因及解决方案: 1. **文件路径不在 `~` 下或不在默认的 `.ssh` 目录中**: - 用户可能将文件创建在了其他目录,或者 `.ssh` 目录不在主目录下(但通常会在)。 2. **文件名不符合 `find` 命令的匹配模式**: - 自定义文件名(如 `dushan_rsa.pub`)可能没有被 `*.pub` 匹配到?实际上,`*.pub` 应该匹配任何以 `.pub` 结尾的文件。但为什么没有匹配到? - 可能是文件不在用户的主目录下,而在某个子目录中,但 `find` 命令是从主目录开始递归搜索的。 - 另一种可能是文件被隐藏(以点开头),但我们的模式没有特别要求,因为 `*.pub` 可以匹配到比如 `.ssh/xxx.pub`。 3. **文件权限问题**: - 如果目录或文件权限过于严格,可能导致 `find` 命令无法进入目录或读取文件。但注意,我们将错误重定向到 `/dev/null`,所以不会看到权限错误信息。 4. **文件确实不存在于主目录下**: - 用户可能将文件创建在了其他位置。 针对以上,我们采取以下步骤: 步骤1:确认自定义公钥文件的位置 如果用户明确记得文件名(例如 `dushan_rsa.pub`),我们可以直接搜索该文件: ```bash find ~ -name "dushan_rsa.pub" 2>/dev/null ``` 步骤2:检查默认的 `.ssh` 目录 通常,SSH 密钥文件存放在 `~/.ssh/` 目录下。我们可以直接检查该目录: ```bash ls -l ~/.ssh/ ``` 查看输出中是否有自定义公钥文件(如 `dushan_rsa.pub`)以及其权限。 步骤3:检查文件权限 如果文件权限不正确,不仅 `find` 可能无法找到,SSH 相关操作也可能失败: - 目录 `~/.ssh` 的权限应为 `700` (drwx------) - 公钥文件的权限应为 `644` 或至少是读权限开放(但私钥必须严格600) 步骤4:直接查看自定义公钥文件 一旦找到文件,使用 `cat` 命令查看: ```bash cat ~/.ssh/dushan_rsa.pub ``` 步骤5:解决 `cat ~/.ssh/id_rsa.pub` 报错的问题 这个错误是因为默认的 `id_rsa.pub` 不存在。用户有自定义名称的公钥,所以应该使用自定义文件名。如果用户希望使用 `ssh` 命令时自动识别自定义密钥,可以配置 `~/.ssh/config` 文件。 例如,为特定主机配置使用自定义密钥: ``` Host myserver HostName example.com User dushan IdentityFile ~/.ssh/dushan_rsa ``` 另外,如果用户在某些场景下(比如使用 `ssh-copy-id`)需要默认使用自定义公钥,可以指定公钥文件: ```bash ssh-copy-id -i ~/.ssh/dushan_rsa.pub user@host ``` 针对 `find` 命令没有找到文件的问题,我们重点排查: - 文件是否真的在用户的主目录下? - 文件名是否拼写正确? 由于用户已经确认创建了自定义pub文件,我们可以直接要求用户提供文件路径,或者通过更宽松的查找来定位。 建议用户执行: ```bash find ~ -name "*.pub" 2>/dev/null ``` 注意:这里去掉了其他条件,只查找所有 `.pub` 文件,看是否能找到。 如果这样还是找不到,那么可能文件不在 `~` 下,或者用户创建文件时指定了其他路径。 综合以上,以下是给用户的回答: </think>### 解决 `cat ~/.ssh/id_rsa.pub` 报错及自定义密钥使用指南 #### 🔍 问题核心分析 您遇到的 `No such file or directory` 错误直接原因是 **默认密钥文件 `id_rsa.pub` 不存在**,而自定义密钥文件(如 `dushan_rsa.pub`)未被系统识别为默认密钥。需解决两个问题: 1. **定位自定义密钥文件** 2. **正确使用/配置自定义密钥** --- ### ✅ 解决方案分步指南 #### 步骤1:精确查找自定义公钥文件 ```bash # 放宽搜索条件(包含所有pub文件) find ~ -name "*.pub" 2>/dev/null # 若仍无结果,全局搜索(需sudo权限) sudo find / -type f -name "dushan_rsa.pub" 2>/dev/null ``` > 📌 若找到类似 `/home/yourname/.ssh/dushan_rsa.pub` 的路径,说明文件存在但命名非默认 #### 步骤2:验证密钥文件权限(关键!) ```bash ls -l ~/.ssh ``` 检查输出是否满足: ```terminal drwx------ .ssh # 目录权限700 ✔️ -rw-r--r-- dushan_rsa.pub # 公钥权限644 ✔️ -rw------- dushan_rsa # 私钥权限600 ✔️ ``` 权限错误时将导致操作失败[^1][^3]: ```bash chmod 644 ~/.ssh/dushan_rsa.pub # 修复公钥权限 chmod 600 ~/.ssh/dushan_rsa # 修复私钥权限 ``` #### 步骤3:查看自定义公钥内容 ```bash # 替换为实际路径 cat ~/.ssh/dushan_rsa.pub ``` 输出示例: ```ssh-rsa ssh-rsa AAAAB3Nza...5Ew== dushan@host ``` #### 步骤4:配置SSH使用自定义密钥 创建或编辑 `~/.ssh/config` 文件: ```bash nano ~/.ssh/config ``` 添加配置(以 `dushan_rsa` 为例): ```config # 全局默认密钥 Host * IdentityFile ~/.ssh/dushan_rsa # 指定服务器专用密钥 Host myserver HostName server.example.com User dushan IdentityFile ~/.ssh/dushan_rsa ``` #### 步骤5:测试SSH连接 ```bash ssh -T git@github.com # 测试GitHub ssh -v dushan@myserver # 测试自定义主机 ``` 观察输出是否含: ```log Authenticating with public key "~/.ssh/dushan_rsa" # 密钥已生效 ``` --- ### ️ 关键注意事项 1. **密钥部署** 将公钥内容(`cat dushan_rsa.pub` 的输出)添加到远程服务器的 `~/.ssh/authorized_keys` 中[^2] ```bash ssh-copy-id -i ~/.ssh/dushan_rsa.pub user@host ``` 2. **SSH Agent** 若需免密操作,添加密钥到代理: ```bash eval "$(ssh-agent -s)" ssh-add ~/.ssh/dushan_rsa ``` 3. **路径验证** 通过绝对路径直接访问: ```bash [ -f ~/.ssh/dushan_rsa.pub ] && echo "验证成功" || echo "文件不存在" ``` --- ### 📚 相关问题延伸 1. **如何修复 `ssh-copy-id` 的 `No such file` 错误?** → 使用 `-i` 指定自定义密钥路径:`ssh-copy-id -i ~/.ssh/dushan_rsa.pub user@host`[^2] 2. **SSH 连接时报 `Permissions 0644 too open` 如何解决?** → 执行 `chmod 600 ~/.ssh/config && chmod 644 ~/.ssh/*.pub` 3. **如何让 Git 使用自定义密钥?** → 设置:`git config core.sshCommand "ssh -i ~/.ssh/dushan_rsa"` 4. **非标准密钥如何通过 ssh-agent 管理?** → 在 `~/.bashrc` 添加:`ssh-add ~/.ssh/dushan_rsa 2>/dev/null` 5. **如何调试 SSH 连接过程?** → 使用 `ssh -vvv user@host` 查看详细认证流程 > 💡 提示:所有解决方案均基于 Linux/Unix 的 OpenSSH 实现,Windows 系统需使用 Git Bash 或 WSL 执行相同命令[^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值