从数据库读取PEM密钥,phpseclib的load方法调用报错求助
解决phpseclib从数据库加载PEM密钥时的
toBytes()错误 首先,咱们先抓核心问题——你大概率是用错了phpseclib的密钥加载方法,再加上数据库存储时的字符串格式问题,才导致了这个报错。下面一步步帮你排查解决:
1. 纠正phpseclib的密钥加载方法
你代码里用的$key->load( $pub );是错误的!phpseclib的RSA类(不管是2.x还是3.x版本),加载密钥的正确方法是loadKey()(2.x)或者loadPublicKey()/loadPrivateKey()(3.x)。你提到“RSA文件中无loadKeys函数”,但loadKey()是肯定存在的,应该是你误写了方法名。
先把代码改成这样试试:
$lightsail = new lightsail(); $pub = $lightsail->getPemByName(); // 先做格式清理 $pub = str_replace(["\\r", "\\n"], ['', "\n"], $pub); $pub = trim($pub); $key = new RSA(); // 替换成正确的loadKey方法 $key->loadKey( $pub );
这一步大概率能直接解决你的报错,因为load()方法根本不是用来加载密钥的,它的参数要求和loadKey()完全不同,才会触发“调用字符串的toBytes()方法”的错误。
2. 彻底修复数据库读取的密钥格式问题
从数据库读取的字符串很容易因为存储/转义出现格式混乱,除了替换\r,你还需要处理这些情况:
- 数据库存储时可能把换行符转义成了
\\n,需要转成真实的换行符\n - 可能存在多余的转义反斜杠(比如phpmyadmin自动转义了引号),需要用
stripslashes()去除 - 首尾可能有多余的空格或换行,用
trim()清理
完整的格式清理代码:
$pub = $lightsail->getPemByName(); // 处理转义的换行和回车 $pub = str_replace(["\\r", "\\n"], ['', "\n"], $pub); // 去除多余转义符 $pub = stripslashes($pub); // 清理首尾空白 $pub = trim($pub);
3. 检查数据库存储的字段配置
确保你存储密钥的字段是TEXT或LONGTEXT类型:
- 不要用
VARCHAR:它有长度限制,会截断长密钥 - 不要用
CHAR:会自动填充空格,破坏密钥格式
另外,在phpmyadmin里查看字段内容,对比原始PEM文件,确保没有丢失换行、没有被自动添加转义字符。
4. 调试密钥内容(排查隐藏问题)
如果还是不行,把从数据库读取的密钥写入临时文件,和你之前能正常运行的密钥对比:
// 写入临时文件 file_put_contents('debug_rsa_key.txt', $pub); // 然后打开这个文件,和你直接写在脚本里的正确密钥逐行对比
重点看:
- 开头的
-----BEGIN PUBLIC KEY-----和结尾的-----END PUBLIC KEY-----是否完整 - 每一行的长度是否和原始PEM一致
- 是否有多余的引号、反斜杠或空格
5. 备选方案:用临时文件加载密钥
如果上述方法都无法解决,可以退回到你之前验证过的“加载文件内容”的方式:把数据库读取的密钥写入临时文件,再加载文件内容:
$pub = $lightsail->getPemByName(); // 创建临时文件 $tempPath = tempnam(sys_get_temp_dir(), 'rsa'); // 写入密钥 file_put_contents($tempPath, $pub); // 加载文件内容 $key = new RSA(); $key->loadKey(file_get_contents($tempPath)); // 删除临时文件 unlink($tempPath);
这种方式和你之前“将密钥写在文件中正常运行”的逻辑完全一致,能绕过大部分字符串格式问题。
内容的提问来源于stack exchange,提问作者ThurstonLevi
相关产品推荐
相关产品推荐

