feat: enhance forwarded messages display by enabling link support
This commit is contained in:
@@ -519,81 +519,27 @@ object MessageCrypto {
|
||||
* @param encryptedData зашифрованный контент (ivBase64:ciphertextBase64)
|
||||
* @param chachaKeyPlain Уже расшифрованный ChaCha ключ+nonce (56 bytes: 32 key + 24 nonce)
|
||||
*/
|
||||
/**
|
||||
* Расшифровка аттачмента зашифрованного через encodeWithPassword (desktop parity)
|
||||
*
|
||||
* Десктоп: decodeWithPassword(keyPlain, data)
|
||||
* 1. keyPlain = chachaDecryptedKey.toString('utf-8') — JS Buffer → UTF-8 string
|
||||
* 2. PBKDF2(keyPlain, 'rosetta', {keySize: 256/32, iterations: 1000}) — SHA256
|
||||
* 3. AES-CBC decrypt
|
||||
* 4. pako.inflate → string
|
||||
*
|
||||
* Ровно то же самое делаем здесь.
|
||||
*/
|
||||
fun decryptAttachmentBlobWithPlainKey(
|
||||
encryptedData: String,
|
||||
chachaKeyPlain: ByteArray
|
||||
): String? {
|
||||
// Один путь, как в десктопе: bytesToJsUtf8String → PBKDF2-SHA256 → AES-CBC → inflate
|
||||
return try {
|
||||
|
||||
// Desktop использует key.toString('binary') → encrypt → decrypt → toString('utf-8') → PBKDF2
|
||||
// Это эквивалентно: raw bytes → Latin1 string → UTF-8 encode → шифрование →
|
||||
// расшифровка → UTF-8 decode → опять UTF-8 для PBKDF2
|
||||
//
|
||||
// Но crypto-js PBKDF2 принимает string и делает UTF-8 encode для получения password bytes
|
||||
// Desktop: PBKDF2(string) → внутри делает UTF-8 encode этой string → использует эти bytes
|
||||
//
|
||||
// КРИТИЧНО: Desktop сохраняет chachaDecryptedKey.toString('utf-8') в БД
|
||||
// И потом использует ЭТУ СТРОКУ напрямую как password для PBKDF2!
|
||||
//
|
||||
// Пробуем РАЗНЫЕ варианты и логируем результат
|
||||
|
||||
// Вариант 1: UTF-8 decode (как Node.js Buffer.toString('utf-8'))
|
||||
val password1 = bytesToJsUtf8String(chachaKeyPlain)
|
||||
val passwordBytes1 = password1.toByteArray(Charsets.UTF_8)
|
||||
|
||||
// Вариант 2: Latin1 decode (каждый byte = char 0-255)
|
||||
val password2 = String(chachaKeyPlain, Charsets.ISO_8859_1)
|
||||
val passwordBytes2 = password2.toByteArray(Charsets.UTF_8)
|
||||
|
||||
// Вариант 3: Raw bytes напрямую (без string conversion)
|
||||
|
||||
// Пробуем расшифровать с КАЖДЫМ вариантом
|
||||
val pbkdf2Key1 = generatePBKDF2Key(password1)
|
||||
val result1 = decryptWithPBKDF2Key(encryptedData, pbkdf2Key1)
|
||||
if (result1 != null) {
|
||||
return result1
|
||||
}
|
||||
|
||||
val pbkdf2Key2 = generatePBKDF2Key(password2)
|
||||
val result2 = decryptWithPBKDF2Key(encryptedData, pbkdf2Key2)
|
||||
if (result2 != null) {
|
||||
return result2
|
||||
}
|
||||
|
||||
val pbkdf2Key3 = generatePBKDF2KeyFromBytes(chachaKeyPlain)
|
||||
val result3 = decryptWithPBKDF2Key(encryptedData, pbkdf2Key3)
|
||||
if (result3 != null) {
|
||||
return result3
|
||||
}
|
||||
|
||||
// V4: Стандартный Java PBKDF2 (PBEKeySpec с char[]) - для совместимости с Android encryptReplyBlob
|
||||
val pbkdf2Key4 = generatePBKDF2KeyJava(password2)
|
||||
val result4 = decryptWithPBKDF2Key(encryptedData, pbkdf2Key4)
|
||||
if (result4 != null) {
|
||||
return result4
|
||||
}
|
||||
|
||||
// V5: Стандартный Java PBKDF2 с UTF-8 password
|
||||
val pbkdf2Key5 = generatePBKDF2KeyJava(password1)
|
||||
val result5 = decryptWithPBKDF2Key(encryptedData, pbkdf2Key5)
|
||||
if (result5 != null) {
|
||||
return result5
|
||||
}
|
||||
|
||||
// V6: Java CharsetDecoder with REPLACE для UTF-8 (может отличаться от bytesToJsUtf8String)
|
||||
val decoder = java.nio.charset.StandardCharsets.UTF_8.newDecoder()
|
||||
decoder.onMalformedInput(java.nio.charset.CodingErrorAction.REPLACE)
|
||||
decoder.onUnmappableCharacter(java.nio.charset.CodingErrorAction.REPLACE)
|
||||
val password6 = decoder.decode(java.nio.ByteBuffer.wrap(chachaKeyPlain)).toString()
|
||||
val passwordBytes6 = password6.toByteArray(Charsets.UTF_8)
|
||||
val pbkdf2Key6 = generatePBKDF2Key(password6)
|
||||
val result6 = decryptWithPBKDF2Key(encryptedData, pbkdf2Key6)
|
||||
if (result6 != null) {
|
||||
return result6
|
||||
}
|
||||
|
||||
null
|
||||
} catch (e: Exception) {
|
||||
val password = bytesToJsUtf8String(chachaKeyPlain)
|
||||
val pbkdf2Key = generatePBKDF2Key(password)
|
||||
decryptWithPBKDF2Key(encryptedData, pbkdf2Key)
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user