создание инстаграмм enc_password - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь создать класс для генерации строки base64 для веб-аутентификации Instagram через C#. в качестве основы для моего кода я использовал этот образец node.js - щелкните он отлично выглядит и отлично работает, но я понятия не имею, как реализовать этот маг. c:

const key = crypto.pseudoRandomBytes(32);
publicKey = '5a0b3cd9a12fef6c786afe28cfceef60550d27ea6657bb15be4a271eaadb0903';
const encryptedKey = tweetnacl.sealedbox.seal(key, Buffer.from(publicKey, 'hex'));

для aes -256-gcm encrypting Я использую библиотеку BouncyCastle, но не могу найти аналогичное действие, например tweetnacl.sealedbox.seal Насколько я понимаю, это действие вернуло uint8array с зашифрованным publicKey

import nacl from 'tweetnacl';
import nonceGenerator from './nonce';
import {overheadLength} from './consts';
import {zero} from './utils';

export default function seal(m, pk){
    var c = new Uint8Array(overheadLength + m.length);

//overheadLength = nacl.box.publicKeyLength + nacl.box.overheadLength;

    var ek = nacl.box.keyPair();
    c.set(ek.publicKey);

    var nonce = nonceGenerator(ek.publicKey, pk);
    var boxed = nacl.box(m, nonce, pk, ek.secretKey);
    c.set(boxed, ek.publicKey.length);

    zero(ek.secretKey);

    return c;
};

мне очень сложно сделать это самому, и я ' Буду очень благодарен за любую помощь.

Ответы [ 2 ]

1 голос
/ 27 июля 2020

Я реализовал его с некоторыми пакетами шифрования, и он хорошо работает для входа в систему.

// Packages need to be installed: 
// Sodium.Core
// System.Security.Cryptography.Algorithms

// The values of publicKey,keyId,version are from shared_data.
// You need to call https://www.instagram.com/data/shared_data/ to get shared_data first
public static string GenerateEncPassword(string password, string publicKey, string keyId, string version)
{
    var time = DateTime.UtcNow.ToTimestamp(); // Unix timestamp
    var keyBytes = publicKey.HexToBytes(); // Convert a hex string to a byte array
    var key = new byte[32];
    new Random().NextBytes(key);
    var iv = new byte[12];
    var tag = new byte[16];
    var plainText = password.ToBytes(); // ToBytes = Encoding.UTF8.GetBytes
    var cipherText = new byte[plainText.Length];

    using (var cipher = new AesGcm(key))
    {
        cipher.Encrypt(nonce: iv,
            plaintext: plainText,
            ciphertext: cipherText,
            tag: tag,
            associatedData: time.ToString().ToBytes());
    }

    var encryptedKey = SealedPublicKeyBox.Create(key, keyBytes);
    var bytesOfLen = ((short)encryptedKey.Length).ToBytes(); // ToBytes = BitConverter.GetBytes(short);
    var info = new byte[] { 1, byte.Parse(keyId) };
    var bytes = info.Concat(bytesOfLen).Concat(encryptedKey).Concat(tag).Concat(cipherText); // Concat means that concat two array

    // expected: #PWD_INSTAGRAM_BROWSER:10:1595671654:ARBQAFWLYGkTT9UU0dyUCkaGTRFu0PH5Ph5s86DUAbZ+B9xon8cKmnqQGaUo7bB4NHCMKQRY69b9LwaJZ1rDw1OFM0LEGtI+KbDuDC0QnfJM6o1no0XPOl73RJoUZ/OfN5nE2q/IdqX0NFinS0faRf8=
    var str = $"#PWD_INSTAGRAM_BROWSER:{version}:{time}:{bytes.ToBase64()}"; // ToBase64 = Convert.ToBase64String
    return str;
}

public static byte[] HexToBytes(this string hex)
{
    return Enumerable.Range(0, hex.Length / 2)
        .Select(x => Convert.ToByte(hex.Substring(x * 2, 2), 16))
        .ToArray();
}

public static T[] Concat<T>(this T[] x, T[] y)
{
    var z = new T[x.Length + y.Length];
    x.CopyTo(z, 0);
    y.CopyTo(z, x.Length);
    return z;
}

private static readonly DateTime _jan1St1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
public static long ToTimestamp(this DateTime d)
{
    return (long)(d.ToUniversalTime() - _jan1St1970).TotalSeconds;
}

Я также поместил его на github gist

Надеюсь, это будет помочь вам.

0 голосов
/ 30 мая 2020

Пробовал портировать на c #, но возникли проблемы с расшифровкой

private static  encryptPassword(string password, string encryptionPubKey, string encryptionKeyId)
 {

            byte[] passwordAsByte = Encoding.ASCII.GetBytes(password);
            byte[] data = Convert.FromBase64String(encryptionPubKey);
            string decoededPubKey = Encoding.UTF8.GetString(data);


            decoededPubKey = decoededPubKey.Replace("-----BEGIN PUBLIC KEY-----", "");
    decoededPubKey = decoededPubKey.Replace("-----END PUBLIC KEY-----", "");
    SecureRandom random = new SecureRandom();
        byte[] randKey = new byte[32];
        random.NextBytes(randKey);
        byte[] iv = new byte[12];
        random.NextBytes(iv);
    //String date = String.valueOf(new Date().getTime() / 1000);
    long tsLong = DateTimeOffset.UtcNow.ToUnixTimeSeconds() / 1000;
        string date = tsLong.ToString();

            var header = new MemoryStream(2);
        header.Write(BitConverter.GetBytes(Convert.ToInt32(1)));
    header.Write(BitConverter.GetBytes(Convert.ToInt32(int.Parse(encryptionKeyId))));
            MemoryStream timeAAD = new MemoryStream(10);
        timeAAD.Write(Encoding.ASCII.GetBytes(date));
//////////////////////////////////////////////////////////////////
    X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(Base64.decode(decoededPubKey, Base64.NO_WRAP));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(publicSpec);
        Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
    byte[] rsaEncrypted = rsaCipher.doFinal(randKey);

            MemoryStream sizeBuff = new MemoryStream(2);
        sizeBuff.order(ByteOrder.LITTLE_ENDIAN);
    sizeBuff.putChar((char) rsaEncrypted.Length);
///////////////////////////////////////////////////////////////////////
    AeadParameters parameters = new AeadParameters(new KeyParameter(randKey), 128, iv, timeAAD.ToArray());
        GcmBlockCipher gcmEngine = new GcmBlockCipher(new AesFastEngine());
        gcmEngine.Init(true, parameters);
    byte[] gcmText = new byte[gcmEngine.GetOutputSize(passwordAsByte.Length)];
        int len = gcmEngine.ProcessBytes(passwordAsByte, 0, passwordAsByte.Length, gcmText, 0);
        gcmEngine.DoFinal(gcmText, len);
    byte[] encPass = Arrays.CopyOfRange(gcmText, 0, gcmText.Length - 16);
        byte[] authTag = Arrays.CopyOfRange(gcmText, gcmText.Length - 16, gcmText.Length);

            var a = header.Position + iv.Length + sizeBuff.Position + rsaEncrypted.Length + authTag.Length + encPass.Length;
            MemoryStream result = new MemoryStream(a);
        result.Write(header.ToArray());
    result.Write(iv);
    result.Write(sizeBuff.ToArray());
    result.Write(rsaEncrypted);
    result.Write(authTag);
    result.Write(encPass);

    //return new Pair(Convert.ToInt64(date), Base64.encodeToString(result.array(), Base64.NO_WRAP));
 }

Это практически готовый код, если будут исправления, пишите в комментариях, я исправлю

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...