Skip to content

Instantly share code, notes, and snippets.

@VulBusters
Created August 9, 2023 08:28
Show Gist options
  • Save VulBusters/c7fbcee55df4313ac3668426f9d0f1c4 to your computer and use it in GitHub Desktop.
Save VulBusters/c7fbcee55df4313ac3668426f9d0f1c4 to your computer and use it in GitHub Desktop.
private static byte[] GetSharedSecret()
{
String clientPrivateKeyPem = PlayerPrefs.GetString(_PlayerPrefs.ClientPrivateKey);
String serverPublicKeyDer = PlayerPrefs.GetString(_PlayerPrefs.ServerPublicKey);
if(String.IsNullOrEmpty(clientPrivateKeyPem))
{
throw new PlayerPrefsItemNotFoundException(_PlayerPrefs.ClientPrivateKey);
}
if(String.IsNullOrEmpty(serverPublicKeyDer))
{
throw new PlayerPrefsItemNotFoundException(_PlayerPrefs.ServerPublicKey);
}
byte[] serverPublicKeyDerByte = Conversion.StringToByteArray(serverPublicKeyDer);
PemReader pemReader = new PemReader(new StringReader(clientPrivateKeyPem));
AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
ECPrivateKeyParameters ecPrivKey = (ECPrivateKeyParameters)keyPair.Private;
ECPublicKeyParameters ecPubKey = (ECPublicKeyParameters)PublicKeyFactory.CreateKey(serverPublicKeyDerByte);
IBasicAgreement aKeyAgree = AgreementUtilities.GetBasicAgreement("ECDH");
aKeyAgree.Init(ecPrivKey);
/* Leading zero statement on ECDH shared secret -> https://github.com/cose-wg/cose-issues/issues/3
* BoucyCastle's BigInteger will convert the shared secret to BigInt and sometime, they remove leading zero
* But Python's Cryptography ECDH shared secret will return byte and keep the leading zero
* Hence, the server and the client is incompatible on this matter
*/
BigInteger sharedSecret = aKeyAgree.CalculateAgreement(ecPubKey);
// so, prepend 0x00 if the shared secret is not equal to 132/2 bytes
byte[] sharedSecretByteArray = sharedSecret.ToByteArray();
if(sharedSecretByteArray.Length != 66)
{
int diff = 66 - sharedSecretByteArray.Length;
byte[] prependedSharedSecret = new byte[sharedSecretByteArray.Length + diff];
for(int i = 0; i < diff; i++)
{
prependedSharedSecret[i] = 0x00;
}
Array.Copy(sharedSecretByteArray, 0, prependedSharedSecret, 1, sharedSecretByteArray.Length);
return prependedSharedSecret;
}
return sharedSecretByteArray;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment