Android 无法创建 EC 密钥对

Android Unable to create EC KeyPair

如标​​题所述,我无法使以下代码生成 ECC 密钥对。

例外情况是:java.security.InvalidParameterException: unknown key size 571

在桌面上,571 是最大密钥大小,我也打算在 Android 应用程序上使用最大密钥大小。我必须怎么做才能让它成为可能?

接下来,是否可以通过 Android 和桌面上的其他库制作更大的密钥?

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Thread thread = new Thread(){
        public void run(){
            try{
                setPriority(Thread.MAX_PRIORITY);
                SecureRandom secureRandom = new SecureRandom();
                KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
                generator.initialize(571, secureRandom);
                KeyPair keyPair = generator.generateKeyPair();
                PublicKey publicKey = keyPair.getPublic();
                PrivateKey privateKey = keyPair.getPrivate();

                System.out.println("EC public: " + publicKey.getAlgorithm() + "\t" + publicKey.getFormat());
                System.out.println("EC private: " + privateKey.getAlgorithm() + "\t" + publicKey.getFormat());
            }
            catch(Exception e){
                System.err.println("EC Exception\n" + e.toString());
                e.printStackTrace();
            }
        }
    };
    thread.start();
}

不需要使用571位曲线。具有 512 位或更高密钥大小的曲线提供 256 位的安全性。这已经足够了——直到量子计算成熟,在那种情况下两者都不够。

目前大多数标准使用质数曲线(F(p) 上的曲线)或特殊曲线,例如 Curve25519。当您指定 571 时,您使用的可能是 F(2^m) 上的曲线,称为 sect571r1。那是一条二元曲线;二元曲线目前不常使用,可能并非每个供应商都提供。

以这种方式选择特定曲线不是很清楚,可能会产生未来的后果。如果因为添加了另一个实现相同大小曲线的提供程序而使用不同的曲线怎么办?

相反,如果您想在素数域上坚持显式强曲线,请使用以下代码:

KeyPairGenerator generator = KeyPairGenerator.getInstance("EC");
generator.initialize(new ECGenParameterSpec("secp521r1"));
KeyPair keyPair = generator.generateKeyPair();
ECPublicKey publicKey = (ECPublicKey) keyPair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey) keyPair.getPrivate();

您也可以尝试添加提供程序 (SpongyCastle) 以获得对更多曲线的支持。确保在这种情况下指定要用于生成器的提供程序。我会认真地建议使用 命名曲线 如上所述。

您只能使用一组离散的 NIST 批准的 EC 曲线,您没有全权委托。

此外,如果您使用的是硬件支持的 Android 密钥库(以后会越来越多),那么只有硬件支持特定的键参数组合 - 例如目前 ( 2020/11) 硬件仅支持 1024 位和 2048 位 RSA 密钥,但不支持 4096 位。