-
-
Save lorenzodifuccia/c857afa47ede66db852e6a25c0a1a027 to your computer and use it in GitHub Desktop.
import base64 | |
import struct | |
import datetime | |
import binascii | |
from urllib.parse import quote_plus | |
# pip install pycryptodomex | |
from Cryptodome import Random | |
from Cryptodome.Cipher import AES | |
# pip install PyNaCl | |
from nacl.public import PublicKey, SealedBox | |
def encrypt_password(key_id, pub_key, password, version=10): | |
key = Random.get_random_bytes(32) | |
iv = bytes([0] * 12) | |
time = int(datetime.datetime.now().timestamp()) | |
aes = AES.new(key, AES.MODE_GCM, nonce=iv, mac_len=16) | |
aes.update(str(time).encode('utf-8')) | |
encrypted_password, cipher_tag = aes.encrypt_and_digest(password.encode('utf-8')) | |
pub_key_bytes = binascii.unhexlify(pub_key) | |
seal_box = SealedBox(PublicKey(pub_key_bytes)) | |
encrypted_key = seal_box.encrypt(key) | |
encrypted = bytes([1, | |
key_id, | |
*list(struct.pack('<h', len(encrypted_key))), | |
*list(encrypted_key), | |
*list(cipher_tag), | |
*list(encrypted_password)]) | |
encrypted = base64.b64encode(encrypted).decode('utf-8') | |
return quote_plus(f'#PWD_INSTAGRAM_BROWSER:{version}:{time}:{encrypted}') | |
print(encrypt_password(72, "b3a328ff28b785092af6a578767877514c93a690a11b9d92ba0ce614c9d5db57", "CHANGE_PASSWORD_HERE")) |
Rust version
use aes_gcm::{aead::NewAead, AeadInPlace, Aes256Gcm, Key, Nonce};
use chrono::Utc;
use rand::Rng;
use rust_sodium::crypto::{box_::PublicKey, sealedbox::curve25519blake2bxsalsa20poly1305::seal};
const VERSION: u8 = 10;
fn read_hex_array(hex_array: &str) -> Vec<u8> {
let hex_array = hex_array.as_bytes();
let mut result = Vec::new();
for i in (0..hex_array.len()).step_by(2) {
let first = hex_array[i];
let second = hex_array.get(i + 1).unwrap_or(&0);
let mut number = match first {
b'a'..=b'f' => 10 + (first - b'a'),
b'A'..=b'F' => 10 + (first - b'A'),
b'0'..=b'9' => first - b'0',
_ => 0,
};
number <<= 4;
number += match second {
b'a'..=b'f' => 10 + (second - b'a'),
b'A'..=b'F' => 10 + (second - b'A'),
b'0'..=b'9' => second - b'0',
_ => 0,
};
result.push(number);
}
result
}
fn generate_enc_password(public_key: &str, key_id: u8, password: &str) -> String {
let public_key = read_hex_array(public_key);
let iv = [0; 12];
let mut key: [u8; 32] = [0; 32];
rand::thread_rng().fill(&mut key);
let time = Utc::now().timestamp().to_string();
// Encrypt the password
let aes = Aes256Gcm::new(Key::from_slice(&key));
let mut encrypted_password = password.as_bytes().to_vec();
let cipher_tag = aes
.encrypt_in_place_detached(
Nonce::from_slice(&iv),
time.as_ref(),
encrypted_password.as_mut_slice(),
)
.unwrap();
// Seal the key with the public key
let mut encrypted_key = seal(&key, &PublicKey::from_slice(&public_key).unwrap());
let mut result = vec![1, key_id];
result.extend_from_slice(&(encrypted_key.len() as u16).to_le_bytes());
result.append(&mut encrypted_key);
result.extend_from_slice(&cipher_tag);
result.append(&mut encrypted_password);
format!(
"#PWD_INSTAGRAM_BROWSER:{}:{}:{}",
VERSION,
time,
base64::encode(result)
)
}
@lorenzodifuccia
Not working.
@suyashjawale, maybe key_id, pub_key
are changed...
@suyashjawale, maybe
key_id, pub_key
are changed...
do you know how solve this problem ?
any update on why it might not work? I'm entering my password yet it still responds that the password is incorrect.
b'{"message":"Sorry, your password was incorrect. Please double-check your password.","status":"fail"}'
(for sure its the right password, also i made sure to receive the current public key and key id from 'https://www.instagram.com/data/shared_data/' using the code:
data = json.loads(requests.get('https://www.instagram.com/data/shared_data/').text)
publicKey = data['encryption']['public_key']
keyId = data['encryption']['key_id']
result = encrypt_password(int(keyId), publicKey, password)
)
yep this not working i changed the keys still getting this error
any solution for this issue?
yep this not working i changed the keys still getting this error
In my case, I encrypt with version 10, but version is 9. You should get actual version from https://www.instagram.com/data/shared_data/ -> encryption.version
Thank you for sharing this!
I am using it in the fb2cal project to properly authenticate: https://github.com/mobeigi/fb2cal/blob/master/fb2cal/utils.py#L22-L50
I was using plain text password before which seems to have only recently stopped working.
Made minor change for header and version to support Facebook Web instead of Instagram.
Question for @tabekg , are you aware of any Facebook Web equivalent to: https://www.instagram.com/data/shared_data/
I'd like to programmatically get the version too for Facebook Web rather than hard coding it.
NodeJS version: https://github.com/unoemon/instagram-enc_passowrd-generator/blob/master/enc_passowrd-generator.js
Patch the JS script: