mirror of
https://github.com/Sneed-Group/pypush-plus-plus
synced 2025-01-09 17:33:47 +00:00
wow that was annoying
This commit is contained in:
parent
766c1c411d
commit
44c1987240
5 changed files with 154 additions and 26 deletions
|
@ -81,7 +81,9 @@ def create_compact_key():
|
||||||
def compact_key(key: ec.EllipticCurvePrivateKey):
|
def compact_key(key: ec.EllipticCurvePrivateKey):
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
|
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
|
||||||
return key.public_key().public_bytes(Encoding.X962, PublicFormat.CompressedPoint)[1:]
|
k = key.public_key().public_bytes(Encoding.X962, PublicFormat.CompressedPoint)
|
||||||
|
assert k[0] == 0x02
|
||||||
|
return k[1:]
|
||||||
|
|
||||||
|
|
||||||
def create_compactable_key():
|
def create_compactable_key():
|
||||||
|
|
|
@ -4,6 +4,8 @@ import struct,time
|
||||||
|
|
||||||
from cryptography.hazmat.primitives.asymmetric import ec
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
from cryptography.hazmat.primitives import hashes
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
logger = logging.getLogger("ids")
|
logger = logging.getLogger("ids")
|
||||||
|
|
||||||
|
@ -18,11 +20,23 @@ class NGMIdentity:
|
||||||
|
|
||||||
def sign_prekey(self):
|
def sign_prekey(self):
|
||||||
timestamp = time.time()
|
timestamp = time.time()
|
||||||
|
# Set decimal to 0
|
||||||
|
timestamp = float(int(timestamp))
|
||||||
to_sign = b"NGMPrekeySignature" + _helpers.compact_key(_helpers.parse_key(self.pre_key)) + struct.pack("<d", timestamp)
|
to_sign = b"NGMPrekeySignature" + _helpers.compact_key(_helpers.parse_key(self.pre_key)) + struct.pack("<d", timestamp)
|
||||||
# Extend to the next multiple of 8
|
# Extend to the next multiple of 8
|
||||||
to_sign += b"\x00" * (8 - (len(to_sign) % 8))
|
#to_sign += b"\x00" * (8 - (len(to_sign) % 8))
|
||||||
print(to_sign)
|
#print(to_sign)
|
||||||
signed = _helpers.parse_key(self.device_key).sign(to_sign, ec.ECDSA(hashes.SHA256()))
|
signed = _helpers.parse_key(self.device_key).sign(to_sign, ec.ECDSA(hashes.SHA256()))
|
||||||
|
a,b = decode_dss_signature(signed)
|
||||||
|
signed = a.to_bytes(32, "big") + b.to_bytes(32, "big")
|
||||||
|
|
||||||
|
# print("SIGNED: " + a.to_bytes(32, "big").hex() + b.to_bytes(32, "big").hex())
|
||||||
|
# print(signed)
|
||||||
|
|
||||||
|
# print("device")
|
||||||
|
# print(_helpers.compact_key(_helpers.parse_key(self.device_key)))
|
||||||
|
# print("pre")
|
||||||
|
# print(_helpers.compact_key(_helpers.parse_key(self.pre_key)))
|
||||||
|
|
||||||
prekey_signed = ids_pb2.PublicDevicePrekey()
|
prekey_signed = ids_pb2.PublicDevicePrekey()
|
||||||
prekey_signed.prekeySignature = signed
|
prekey_signed.prekeySignature = signed
|
||||||
|
|
|
@ -219,30 +219,30 @@ def register(
|
||||||
"sub-services": [],
|
"sub-services": [],
|
||||||
"users": [
|
"users": [
|
||||||
{
|
{
|
||||||
|
# "client-data": {
|
||||||
|
# "public-message-identity-key": identity.encode(),
|
||||||
|
# "public-message-identity-version": 2,
|
||||||
|
# "supports-avless": True,
|
||||||
|
# "supports-co": True,
|
||||||
|
# "supports-gft-calls": True,
|
||||||
|
# "supports-gft-errors": True,
|
||||||
|
# "supports-modern-gft": True,
|
||||||
|
# "supports-self-one-to-one-invites": True,
|
||||||
|
# },
|
||||||
"client-data": {
|
"client-data": {
|
||||||
"public-message-identity-key": identity.encode(),
|
"public-message-ngm-device-prekey-data-key": ngm.sign_prekey(),
|
||||||
"public-message-identity-version": 2,
|
"supports-avless": True,
|
||||||
"supports-avless": True,
|
"public-message-identity-key": identity.encode(),
|
||||||
"supports-co": True,
|
"supports-gft-calls": True,
|
||||||
"supports-gft-calls": True,
|
"public-message-identity-version": 2.0,
|
||||||
"supports-gft-errors": True,
|
"supports-co": True,
|
||||||
"supports-modern-gft": True,
|
"supports-gft-errors": True,
|
||||||
"supports-self-one-to-one-invites": True,
|
"supports-self-one-to-one-invites": True,
|
||||||
},
|
"supports-modern-gft": True,
|
||||||
# "client-data": {
|
"public-message-identity-ngm-version": 12.0,
|
||||||
# "public-message-ngm-device-prekey-data-key": b"\n \xb4\\\x15\x8e\xa4\xc8\xe5\x07\x98\tp\xd0\xa4^\x84k\x05#Ep\xa9*\xcd\xadt\xf5\xb0\xfb\xa6_ho\x12@\xe3\xf5\xcaOwh\xfd\xb9\xecD\t\x0e\x9e\xb8\xb0\xa1\x1c=\x92\x9dD/lmL\xde.\\o\xeb\x15>\x9f\xae\xd9\xf9\xd1\x9c*\x8dU\xe0\xd2\xdeo\xb2\xcb\xd8\xf8i\xd4\xd0a^\t!\x0fa\xb2\xddI\xfc_*\x19\xb2\xf0#\x12\xe0@\xd9A",
|
#"device-key-signature": b"0a\x04\x14\x1d\xb02~\xefk&\xf8\r;R\xa4\x95c~\x8a\x90H\x85\xb0\x02\x01\x01\x04F0D\x02 @\xce\xa7P6\x89\x92Wf\x87\xc9\xc5M-\xb1\xe5Q\x9f\x7fKi\x1bp\xd5\x12\x1c,:\xdb\xed\x08\x12\x02 l\xfd\\\xe2\xd3:,\xc1\xd8\x08|\xbe\x05M\x12\xee@\xc2=eR8:\xa7h3u|\x83ia\x19",
|
||||||
# "supports-avless": True,
|
},
|
||||||
# "public-message-identity-key": b"0\x81\xf6\x81C\x00A\x04\x87\x1e\xeb\xe4u\x0b\xa3\x9e\x9c\xbc\xf8rK\x1e\xfe44%f$\x1d\xe8\xbb\xc6\xbdCD\x9ckv K\xc1\x1e\xb1\xdf4\xc8S6\x0f\x92\xd0=\x1e\x84\x9c\xc5\xa5\xb6\xb7}\xdd\xec\x1e\x1e\xd8Q\xd8\xca\xdb\x07'\xc7\x82\x81\xae\x00\xac0\x81\xa9\x02\x81\xa1\x00\xa8 \xfc\x9f\xa6\xb0V2\xce\x1c\xa7\x13\x9e\x03\xd1\xd8\x97a\xbb\xdd\xac\x86\xb8\x10(\x89\x13QP\x8f\xf0+EP\xd1\xb06\xee\x94\xcd\xa8\x9e\xf1\xedp\xa4\x9726\x1e\xe9\xab\xd4\xcb\xac\x05\xd7\x8c?\xbb\xa2\xde,\xfe\r\x1a\xb9\x88W@\x99\xec\xa0]\r\x1a>dV\xb2@\xc5P\xf3m\x80y\xf5\xa0G\xae\xd8h\x92\xef\xca\x85\xcbB\xed\xa9W\x8c\x13\xd4O\xdbYI2\xdcM\x1f\xf6c\x17\x1c\xd1v\xdd\xbcc\xac,&V\xfd\x07\xa0\xc3\x9f\x00\x1f\xc6\xe4\x02u\x12p\x8f\xe2\xb0\x14\xfai\x12\xbb\xa6\x9a6Q\xa5\xde+\x9e{\xcf\xc8\x1b}\x02\x03\x01\x00\x01",
|
"kt-loggable-data": ngm.generate_loggable_data(),
|
||||||
# "supports-gft-calls": True,
|
|
||||||
# "public-message-identity-version": 2.0,
|
|
||||||
# "supports-co": True,
|
|
||||||
# "supports-gft-errors": True,
|
|
||||||
# "supports-self-one-to-one-invites": True,
|
|
||||||
# "supports-modern-gft": True,
|
|
||||||
# "public-message-identity-ngm-version": 12.0,
|
|
||||||
# "device-key-signature": b"0a\x04\x14\x1d\xb02~\xefk&\xf8\r;R\xa4\x95c~\x8a\x90H\x85\xb0\x02\x01\x01\x04F0D\x02 @\xce\xa7P6\x89\x92Wf\x87\xc9\xc5M-\xb1\xe5Q\x9f\x7fKi\x1bp\xd5\x12\x1c,:\xdb\xed\x08\x12\x02 l\xfd\\\xe2\xd3:,\xc1\xd8\x08|\xbe\x05M\x12\xee@\xc2=eR8:\xa7h3u|\x83ia\x19",
|
|
||||||
# },
|
|
||||||
# "kt-loggable-data": b'\n"\n \rl\xbe\xca\xf7\xe8\xb2\x89k\x18\x1e\xb9,d\xf8\xe2\n\xbf\x8d\xe1E\xd6\xf3T\xcb\xd9\x99d\xd1mk\xeb\x10\x0c\x18\x05',
|
|
||||||
|
|
||||||
"uris": uris,
|
"uris": uris,
|
||||||
"user-id": user_id,
|
"user-id": user_id,
|
||||||
|
|
80
ids/test.js
Normal file
80
ids/test.js
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
const { subtle } = globalThis.crypto;
|
||||||
|
|
||||||
|
const fromHexString = (hexString) =>
|
||||||
|
Uint8Array.from(hexString.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
|
||||||
|
|
||||||
|
function hexToBytes(hex) {
|
||||||
|
let bytes = [];
|
||||||
|
for (let c = 0; c < hex.length; c += 2)
|
||||||
|
bytes.push(parseInt(hex.substr(c, 2), 16));
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert a byte array to a hex string
|
||||||
|
function bytesToHex(bytes) {
|
||||||
|
let hex = [];
|
||||||
|
for (let i = 0; i < bytes.length; i++) {
|
||||||
|
let current = bytes[i] < 0 ? bytes[i] + 256 : bytes[i];
|
||||||
|
hex.push((current >>> 4).toString(16));
|
||||||
|
hex.push((current & 0xF).toString(16));
|
||||||
|
}
|
||||||
|
return hex.join("");
|
||||||
|
}
|
||||||
|
function byteToUint8Array(byteArray) {
|
||||||
|
var uint8Array = new Uint8Array(byteArray.length);
|
||||||
|
for(var i = 0; i < uint8Array.length; i++) {
|
||||||
|
uint8Array[i] = byteArray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return uint8Array;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EXPECTED = "4e474d5072656b65795369676e6174757265e6565a7b37344b65f695db4f80d4515532a075cbb27a3d4dcbda949e9a571a640000c068e343d941"
|
||||||
|
const SIGNED = "54e0dc4956f7ce0e559b83e0d93d3a2d41074b59992100ab8a71c807fa50d6d2053da7f16621c799486f821a6ac627ffc76b4d63c11b9c75ef8c85d15c54aff4"
|
||||||
|
const DEV_KEY = "04ab72d39f38cbadfc8914e45726ec9a41732fad9eb6e6e536ea6ef6b954328a030fe1ed4c3332c98f91d4c079d43163e865d6c23b33394c69a131f51415ff0eda"
|
||||||
|
|
||||||
|
async function test() {
|
||||||
|
let key = await subtle.importKey("raw",byteToUint8Array(hexToBytes(DEV_KEY)),{
|
||||||
|
name: "ECDSA",
|
||||||
|
namedCurve: "P-256",
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
["verify"],
|
||||||
|
);
|
||||||
|
let signature = byteToUint8Array(hexToBytes(SIGNED))
|
||||||
|
|
||||||
|
let expected = byteToUint8Array(hexToBytes(EXPECTED));
|
||||||
|
console.log(key);
|
||||||
|
let t = await subtle.verify({
|
||||||
|
name: "ECDSA",
|
||||||
|
hash: "SHA-256"
|
||||||
|
}, key, signature, expected)
|
||||||
|
console.log(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEV_PRIV_KEY = "308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420a1b2ef67c92859ae7677c7bcc657c33fac4059448aff9602b8e6a313aa0d17caa144034200044eaf956b8619406cfd506232ded21fd5349f1ac8acc28b3b73bc8e293bc56ee0e4cfb4c9baf3c7603baa7716d0fe9c781e48f4bba5f90167f68d7f6c0e4b8cd8"
|
||||||
|
async function test2() {
|
||||||
|
//console.log(Uint8Array.from(Buffer.from(DEV_PRIV_KEY, 'hex')))
|
||||||
|
let key = await subtle.importKey("pkcs8",fromHexString(DEV_PRIV_KEY),{
|
||||||
|
name: "ECDSA",
|
||||||
|
namedCurve: "P-256",
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
["sign"],
|
||||||
|
);
|
||||||
|
let to_sign = byteToUint8Array(hexToBytes(EXPECTED));
|
||||||
|
|
||||||
|
let signature = await subtle.sign({
|
||||||
|
name: "ECDSA",
|
||||||
|
hash: "SHA-256"
|
||||||
|
}, key, to_sign)
|
||||||
|
console.log(signature)
|
||||||
|
}
|
||||||
|
(async() => {
|
||||||
|
console.log('before start');
|
||||||
|
|
||||||
|
await test();
|
||||||
|
await test2();
|
||||||
|
|
||||||
|
console.log('after start');
|
||||||
|
})();
|
32
ids/test.py
Normal file
32
ids/test.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
import time
|
||||||
|
from cryptography.hazmat.primitives.asymmetric import ec
|
||||||
|
from cryptography.hazmat.primitives import hashes
|
||||||
|
import _helpers
|
||||||
|
import struct
|
||||||
|
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat, PrivateFormat, NoEncryption
|
||||||
|
from cryptography.hazmat.primitives.asymmetric.utils import decode_dss_signature
|
||||||
|
|
||||||
|
def sign_prekey():
|
||||||
|
pre_key = _helpers.create_compactable_key()
|
||||||
|
device_key = _helpers.create_compactable_key()
|
||||||
|
print("DEV PRIV KEY: " + _helpers.parse_key(device_key).private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption()).hex())
|
||||||
|
timestamp = time.time()
|
||||||
|
# Set decimal to 0
|
||||||
|
timestamp = float(int(timestamp))
|
||||||
|
to_sign = b"NGMPrekeySignature" + _helpers.compact_key(_helpers.parse_key(pre_key)) + struct.pack("<d", timestamp)
|
||||||
|
print("EXPECTED: " + to_sign.hex())
|
||||||
|
# Extend to the next multiple of 8
|
||||||
|
#to_sign += b"\x00" * (8 - (len(to_sign) % 8))
|
||||||
|
#print(to_sign)
|
||||||
|
signed = _helpers.parse_key(device_key).sign(to_sign, ec.ECDSA(hashes.SHA256()))
|
||||||
|
# Decode the signature into the tuple
|
||||||
|
a,b = decode_dss_signature(signed)
|
||||||
|
|
||||||
|
print("SIGNED: " + a.to_bytes(32, "big").hex() + b.to_bytes(32, "big").hex())
|
||||||
|
|
||||||
|
|
||||||
|
#print("SIGNED: " + signed.hex())
|
||||||
|
|
||||||
|
print("DEVICE KEY: " + _helpers.parse_key(device_key).public_key().public_bytes(Encoding.X962, PublicFormat.UncompressedPoint).hex())
|
||||||
|
|
||||||
|
sign_prekey()
|
Loading…
Reference in a new issue