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:支持
RSA密钥如何成为ssh-rsa密钥?
ssh-rsa是SSH协议对RSA密钥的特定标识,核心是用SHA-1哈希结合RSA签名。要让AndroidKeyStore生成的RSA密钥符合这个类型:- 生成密钥时指定签名算法为
SHA1withRSA - 把公钥转换成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
相关产品推荐
相关产品推荐

