Закрытый ключ Bouncy Castle Curve25519 из вывода Scrypt
Я пытаюсь добиться шифрования ECIES, для которого работает приведенный ниже код.
X9ECParameters ecP = CustomNamedCurves.getByName("curve25519");
ECParameterSpec ecSpec = EC5Util.convertToSpec(ecP);
BigInteger d = new BigInteger("145642755521911534651321230007534120304391871461646461466464667494947990");
ECPrivateKeySpec priKeySpec = new ECPrivateKeySpec(
d, // d
ecSpec);
ECPoint Q = new FixedPointCombMultiplier().multiply(params.getG(), d.multiply(BigInteger.valueOf(-1)));
Q = Q.normalize();
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(
new ECPoint(Q.getAffineXCoord().toBigInteger(), Q.getAffineYCoord().toBigInteger()), // Q
ecSpec);
KeyFactory factTrial = KeyFactory.getInstance("EC", BouncyCastleProvider.PROVIDER_NAME);
BCECPrivateKey sKey = (BCECPrivateKey) factTrial.generatePrivate(priKeySpec);
PublicKey vKey = factTrial.generatePublic(pubKeySpec);
Cipher c = Cipher.getInstance("ECIESwithAES-CBC",BouncyCastleProvider.PROVIDER_NAME);
byte[] encodeBytes = c.doFinal(data.getBytes());
String encrypt = Base64.getEncoder().encodeToString(encodeBytes);
Cipher c2 = Cipher.getInstance("ECIESwithAES-CBC",BouncyCastleProvider.PROVIDER_NAME);
c2.init(Cipher.DECRYPT_MODE,sKey, c.getParameters());
byte[] decodeBytes = c2.doFinal(encodeBytes);
String deCrypt = new String(decodeBytes,"UTF-8");
Проблема заключается в элементе закрытого ключа "d". Если я попытаюсь заменить его выводом хэша scrypt, закрытый ключ не будет преобразован в экземпляр PrivateKey.
Я просмотрел сетевые ресурсы https://github.com/bcgit/bc-java/issues/251, https://crypto.stackexchange.com/questions/51703/how-to-convert-from-curve25519-33-byte-to-32-byte-representation, https://crypto.stackexchange.com/questions/72134/raw-curve25519-public-key-points.
Приведенные выше ресурсы показывают, что способ интерпретации закрытого ключа Bouncy Castle для Curve25519 отличается от того, как предлагают некоторые интернет-ресурсы. В сообщении https://crypto.stackexchange.com/questions/51703/how-to-convert-from-curve25519-33-byte-to-32-byte-representation упоминается следующее.
Согласно статье curve25519, открытый ключ x25519 может быть представлен 32 байтами.
Библиотека x25519, которую я использую (bouncycastle), однако дает мне 33-байтовое представление в соответствии с этим стандартом.
Я новичок в ECC, эти ресурсы меня сбивают с толку, разница между длинами, стилем кодирования большой и маленький.
Я пробовал libSodium 'crypto_box_easy' и 'crypto_box_open_easy' через его привязку к Java, и все работает нормально. 32-байтовый вывод scrypt используется "crypto_box_seed_keypair" для генерации пары ключей, которая используется для процесса шифрования.
Как я вижу, здесь задействована некоторая математика, которой мне сейчас не хватает или я не вижу конверсии.
Мне нужно пройти по этому маршруту Вывод Scrypt -> пара ключей -> использовать для шифрования
Прямое использование KeyGenerator из BC работает, но при этом используется SecureRandom, но мне нужен вывод Scrypt, чтобы он работал как закрытый ключ.
Вопросы:
Я очень признателен, если кто-то поможет мне понять разницу между подходами libSodium и Bouncy Castle. libSodium упоминает, что использует X25519. Когда я пытаюсь создать ключ X25519 из 32 байтов, но BC Cipher(ECIESwithAES-CBC), тогда жалуются, что это не точка EC, из этого ресурса https://github.com/bcgit/bc-java/issues/251' похоже, и в этом есть отличия (Curve25519 vs X25519).
Закрытый ключ d, как его интерпретировать. Я видел эти случайные значения в документации и тестовых примерах Bouncy Castle, это просто число из предписанного диапазона для действительных ключей? Перед созданием экземпляра BigInteger это число обрабатывается (от младшего к старшему). Я имею в виду, что необработанное значение 'd' в моем примере кода было преобразовано из какого-то другого числа?
Меня очень смущает борьба между пониманием различных механизмов Curve25519 и самого BC API.
Мне бы очень помогли некоторые указания по дальнейшим моим исследованиям.