I have a client (an Android app with Java) and a Node.js server. I want to generate a shared secret using the client’s and server’s Diffie-Hellman public keys.
The server and the client send their Diffie-Hellman public keys to each other over TCP (Transmission Control Protocol) so that they may generate a shared secret. When the server sends its public key to the client as a base64 string, I can successfully convert this string to bytes on the client-side.
The problem is that, when converting the bytes to a PublicKey
instance on the marked Line 8, I get the error:
java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed to construct sequence from byte[]: DER length more than 4 bytes: 33
Here’s my Java code:
public boolean generateSharedSecret() throws Exception {
byte[] serverDiffieHellmanPublicKey = receiveDiffieHellmanPublicKey();
Log.e("String Length", String.valueOf(Base64.encodeToString(serverDiffieHellmanPublicKey, Base64.DEFAULT).length())); // Outputs 90.
Log.e("Bytes Length", String.valueOf(serverDiffieHellmanPublicKey.length)); // Outputs 64.
KeyFactory keyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(serverDiffieHellmanPublicKey); // Line 8
PublicKey dhPublicKeyFromServer = keyFactory.generatePublic(x509EncodedKeySpec);
// ...
}
public byte[] receiveDiffieHellmanPublicKey() {
try {
Socket socket = new Socket("185.255.95.248", 1211);
InputStream inputStream = socket.getInputStream();
byte[] buffer = new byte[1024];
int bytesRead = inputStream.read(buffer);
String keyString = new String(buffer, 0, bytesRead);
return Base64.decode(keyString, Base64.DEFAULT);
} catch (Exception ignore) {}
}
Here’s my Node.js code:
const net = require("net");
const crypto = require("crypto");
const dh = crypto.createDiffieHellman(512);
const serverDiffieHellman = crypto.generateDiffieHellman(dh.getPrime());
net.createServer((socket) => {
socket.on("connect", () => socket.write(serverDiffieHellman.getPublicKey().toString("base64")));
}).listen(1211, "185.255.95.248", () => console.log("TCP server is running..."));
Any help will be pleasantly appreciated. Thanks, regards…