Открытый ключ в строку, а затем обратно в открытый ключ Java
Так что у меня есть этот кусок кода, который я пытаюсь выполнить некоторые преобразования, так что сначала я генерирую открытый ключ и распечатываю его, а затем преобразую в байтах, затем в строку, после чего я преобразую его обратно в байты, но когда я преобразую его обратно в байты значение изменяется для байта, поэтому сгенерированный открытый ключ не совпадает с верхним, как вы можете видеть в выводе ниже
//generating public key
PublicKey public_key = CryptographyHelper.ellipticCurveCrypto().getPublic();
System.out.println("PUBLIC KEY::" + public_key);
//converting public key to byte
byte[] byte_pubkey = public_key.getEncoded();
System.out.println("\nBYTE KEY::: " + byte_pubkey);
//converting byte to String
String str_key = Arrays.toString(byte_pubkey);
System.out.println("\nSTRING KEY::" + str_key);
//converting string to Bytes
byte_pubkey = str_key.getBytes();
System.out.println("BYTE KEY::" + byte_pubkey);
//converting it back to public key
KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");
public_key = (ECPublicKey) factory.generatePublic(new X509EncodedKeySpec(byte_pubkey));
System.out.println("FINAL OUTPUT" + public_key);
Выход
PUBLIC KEY::EC Public Key [4d:53:40:86:3f:a8:91:49:b6:27:b5:58:14:b8:8b:f1:ff:8a:78:70]
X: c8e1028cad7b105814d4a2e0e292f5f7904aad7b6cbc46a5
Y: 312272321a1ba4ff14caa73b42acb35eb025d9f6fc2ca6b3
BYTE KEY::: [B@1a1d6a08
STRING KEY::[48, 70, 48, 16, 6, 7, 42, -122, 72, -50, 61, 2, 1, 6, 5, 43, -127, 4, 0, 31, 3, 50, 0, 4, -56, -31, 2, -116, -83, 123, 16, 88, 20, -44, -94, -32, -30, -110, -11, -9, -112, 74, -83, 123, 108, -68, 70, -91, 49, 34, 114, 50, 26, 27, -92, -1, 20, -54, -89, 59, 66, -84, -77, 94, -80, 37, -39, -10, -4, 44, -90, -77]
BYTE KEY[B@37d31475
Exception in thread "main" java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed to construct sequence from byte[]: Extra data detected in stream
at org.bouncycastle.jcajce.provider.asymmetric.util.BaseKeyFactorySpi.engineGeneratePublic(Unknown Source)
at org.bouncycastle.jcajce.provider.asymmetric.ec.KeyFactorySpi.engineGeneratePublic(Unknown Source)
at java.security.KeyFactory.generatePublic(KeyFactory.java:328)
at blahblah.Driver.main(Driver.java:44)
C:\Users\blahblah\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 1 second)
у меня есть ошибка, потому что, когда я преобразовываю его обратно в байты во второй раз, а затем, когда он преобразует обратно в открытый ключ, он становится недействительным, следовательно, ошибка
Дополнительная информация
но когда я просто делаю это, это работает нормально, но моя цель - сначала преобразовать открытый ключ в строку, как потом преобразовать эту строку в тип открытый ключ, и единственный способ сделать это - преобразовать открытый ключ в строку введите в тип байта, а затем преобразовать его обратно в открытый ключ, я не могу преобразовать строку непосредственно в открытый ключ, так как он не будет работать
1 ответ
Вам необходимо использовать систему кодирования Base64 при конвертации в тип String.
Метод tostring() использует кодировку по умолчанию JVM, которая не поддерживает ваши символы.
PublicKey public_key = CryptographyHelper.ellipticCurveCrypto().getPublic();
System.out.println("PUBLIC KEY::" + public_key);
//converting public key to byte
byte[] byte_pubkey = public_key.getEncoded();
System.out.println("\nBYTE KEY::: " + byte_pubkey);
//converting byte to String
String str_key = Base64.getEncoder().encodeToString(byte_pubkey);
// String str_key = new String(byte_pubkey,Charset.);
System.out.println("\nSTRING KEY::" + str_key);
//converting string to Bytes
byte_pubkey = Base64.getDecoder().decode(str_key);
System.out.println("BYTE KEY::" + byte_pubkey);
//converting it back to public key
KeyFactory factory = KeyFactory.getInstance("ECDSA", "BC");
public_key = (ECPublicKey) factory.generatePublic(new X509EncodedKeySpec(byte_pubkey));
System.out.println("FINAL OUTPUT" + public_key);
Вот полный пример создания открытых и закрытых ключей через JCE с использованием ECDSA из Bouncy Castle.
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import static org.bouncycastle.jce.ECNamedCurveTable.getParameterSpec;
public class PublicPrivateKeyExample {
static {
Security.addProvider(new BouncyCastleProvider());
}
private static final SecureRandom DEFAULT_SECURE_RANDOM;
static {
DEFAULT_SECURE_RANDOM = new SecureRandom();
DEFAULT_SECURE_RANDOM.nextBytes(new byte[64]);
}
public static void main(String[] args) throws Exception {
// -----
// Create a random key-pair using ECDSA provided by bcprov-jdk15on from Bouncy Castle and encode as base64
// strings
// -----
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ECDSA", "BC");
keyPairGenerator.initialize(getParameterSpec("secp521r1"), DEFAULT_SECURE_RANDOM);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
Base64.Encoder encoder = Base64.getEncoder();
String publicKeyStr = encoder.encodeToString(publicKey.getEncoded());
String privateKeyStr = encoder.encodeToString(privateKey.getEncoded());
// -----
// Decode the base64 public and private keys back to a JCE's PublicKey and PrivateKey
// -----
KeyFactory keyFactory = KeyFactory.getInstance("ECDSA", "BC");
Base64.Decoder decoder = Base64.getDecoder();
PublicKey decodedPublicKey = keyFactory.generatePublic(new X509EncodedKeySpec(decoder.decode(publicKeyStr)));
PrivateKey decodedPrivateKey =
keyFactory.generatePrivate(new PKCS8EncodedKeySpec(decoder.decode(privateKeyStr)));
assert publicKey.getEncoded() == decodedPublicKey.getEncoded();
assert privateKey.getEncoded() == decodedPrivateKey.getEncoded();
}
}
Это было протестировано с использованием Java 8 со следующим:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency>