You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AndroidKeyStore密钥实现SSH客户端认证失败问题排查

问题排查与解决方案
  • 匹配SSH兼容的密钥签名算法
    SSH的ssh-rsa对应SHA1withRSA签名算法,而AndroidKeyStore生成的RSA密钥默认可能用SHA-256/RSA这类新算法,部分旧SSH服务器只认传统的ssh-rsa。生成密钥时得明确指定签名算法为SHA1withRSA:
KeyPairGeneratorSpec spec = new KeyPairGeneratorSpec.Builder(context)
        .setAlias("ssh_key")
        .setKeySize(2048)
        .setSignatureAlgorithm("SHA1withRSA")
        .setSubject(new X500Principal("CN=SSH Key"))
        .setSerialNumber(BigInteger.ONE)
        .setStartDate(new Date())
        .setEndDate(new Date(System.currentTimeMillis() + 365L * 24 * 60 * 60 * 1000))
        .build();

如果服务器支持新算法,也可以在SSH客户端配置中启用rsa-sha2-256/rsa-sha2-512,不用改密钥算法。

  • 确保密钥用途包含签名权限
    AndroidKeyStore生成的密钥默认用途可能不全,必须明确指定签名相关用途:
KeyProperties.PURPOSE_SIGNATURE | KeyProperties.PURPOSE_NON_REPUDIATION

生成时要把这个参数加到密钥用途里,否则私钥无法用于SSH签名验证。

  • 修复自定义KeyPairProvider的签名逻辑
    如果用JSch之类的SSH库,自定义KeyPairProvider时不能用默认的签名实现——因为AndroidKeyStore的私钥无法导出,必须用Android系统的Signature类来处理签名:
@Override
public byte[] sign(byte[] data) throws Exception {
    Signature signature = Signature.getInstance("SHA1withRSA");
    signature.initSign(getPrivateKeyFromKeyStore());
    signature.update(data);
    return signature.sign();
}

别直接用JSch自带的签名工具,得适配AndroidKeyStore的密钥操作限制。

疑问解答
  • AndroidKeyStore是否支持authorized_keys中的密钥类型?
    支持,但要匹配密钥类型和对应的签名算法:

    • RSA:支持ssh-rsa(SHA1withRSA)、rsa-sha2-256(SHA256withRSA)、rsa-sha2-512(SHA512withRSA)
    • ECDSA:支持ecdsa-sha2-nistp256等对应椭圆曲线的类型
      注意Android版本限制:Android 6.0(API 23)及以上支持更多算法,旧版本可能只支持基础的ssh-rsa。
  • RSA密钥如何成为ssh-rsa密钥?
    ssh-rsa是SSH协议对RSA密钥的特定标识,核心是用SHA-1哈希结合RSA签名。要让AndroidKeyStore生成的RSA密钥符合这个类型:

    1. 生成密钥时指定签名算法为SHA1withRSA
    2. 把公钥转换成SSH格式:从KeyStore获取公钥后,编码成Base64,加上ssh-rsa前缀和注释,比如:
      ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... android_ssh_key
      
      代码示例:
      Certificate cert = keyStore.getCertificate("ssh_key");
      PublicKey publicKey = cert.getPublicKey();
      String sshPubKey = "ssh-rsa " + Base64.encodeToString(publicKey.getEncoded(), Base64.NO_WRAP) + " android_ssh_key";
      
      把这个字符串加到服务器的authorized_keys里就行。

内容的提问来源于stack exchange,提问作者user1933677

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 22:25:07