Passport Files and Documents
We use the driver's license scope here to show decryption of ID document data and passport files for front side scan, reverse side scan, selfie photo, and translation scan. That should cover most of the field types in Telegram Passport.
Sections below are referring to the test methods in Driver's License Scope Tests collection. Here are the steps:
- Authorization Request
- Driver's License Info
- Passport Message
- Credentials
- ID Document Data
- Passport File
Authorization Request
We start by generating an authorization URI. Since a driver's license is considered as a proof of identity, we ask for optional data selfie with document and translation document scan as well.
Driver's License Info
As a user, provide information for the required fields: front side, reverse side, and document number. Also, test methods here expect a selfie photo and a file for translation scan.
Click the Authorize button at the end.
Passport Message
This test method checks for a Passport message with a driver's license element on it.
Credentials
We decrypt credentials using the RSA private key and verify that the same nonce is used.
RSA key = EncryptionKey.ReadAsRsa();
IDecrypter decrypter = new Decrypter();
Credentials credentials = decrypter.DecryptCredentials(
passportData.Credentials,
key
);
bool isSameNonce = credentials.Nonce == "Test nonce for driver's license";
ID Document Data
In our test case, there is only 1 item in the message.passport_data.data
array and that's the encrypted element for
the driver's license scope.
We can get information such as document number and expiry date for the license from that element:
IdDocumentData licenseDoc = decrypter.DecryptData<IdDocumentData>(
encryptedData: element.Data,
dataCredentials: credentials.SecureData.DriverLicense.Data
);
Passport File
Passport file is an encrypted JPEG file on Telegram servers. You need to download the passport file and decrypt it using its accompanying file credentials to see the actual JPEG file content. In this section we try to demonstrate different use cases that you might have for such files.
No matter the method used, the underlying decryption logic is the same. It really comes down to your decision on working with streams vs. byte arrays. IDecrypter gives you both options.
Front Side File
A pretty handy extension method is used here to stream writing the front side file to disk. Method DownloadAndDecryptPassportFileAsync does a few things:
- Makes an HTTP request to fetch the encrypted file's info using its passport file_id
- Makes an HTTP request to download the encrypted file using its file_path
- Decrypts the encrypted file
- Writes the actual content to the destination stream
File encryptedFileInfo;
using (System.IO.Stream stream = System.IO.File.OpenWrite("/path/to/front-side.jpg"))
{
encryptedFileInfo = await bot.DownloadAndDecryptPassportFileAsync(
element.FrontSide, // PassportFile object for front side
credentials.SecureData.DriverLicense.FrontSide, // front side FileCredentials
stream // destination stream for writing the JPEG content to
);
}
warning
This method is convenient to use but gives you the least amount of control over the operations.
Reverse Side File
Previous method call is divided into two operations here for reverse side of the license. Streams are used here as well.
File encryptedFileInfo;
using (System.IO.Stream
encryptedContent = new System.IO.MemoryStream(element.ReverseSide.FileSize),
decryptedFile = System.IO.File.OpenWrite("/path/to/reverse-side.jpg")
) {
// fetch the encrypted file info and download it to memory
encryptedFileInfo = await bot.GetInfoAndDownloadFileAsync(
element.ReverseSide.FileId, // file_id of passport file for reverse side
encryptedContent // stream to copy the encrypted file into
);
// ensure memory stream is at the beginning before reading from it
encryptedContent.Position = 0;
// decrypt the file and write it to disk
await decrypter.DecryptFileAsync(
encryptedContent,
credentials.SecureData.DriverLicense.ReverseSide, // reverse side FileCredentials
decryptedFile // destination stream for writing the JPEG content to
);
}
Selfie File
We deal with selfie photo as a byte array. This is essentially the same operation as done above via streams. We also post the selfie photo to a chat.
// fetch the info of the passport file(selfie) residing on Telegram servers
File encryptedFileInfo = await bot.GetFileAsync(element.Selfie.FileId);
// download the encrypted file and get its bytes
byte[] encryptedContent;
using (System.IO.MemoryStream
stream = new System.IO.MemoryStream(encryptedFileInfo.FileSize)
)
{
await bot.DownloadFileAsync(encryptedFileInfo.FilePath, stream);
encryptedContent = stream.ToArray();
}
// decrypt the content and get bytes of the actual selfie photo
byte[] selfieContent = decrypter.DecryptFile(
encryptedContent,
credentials.SecureData.DriverLicense.Selfie
);
// send the photo to a chat
using (System.IO.Stream stream = new System.IO.MemoryStream(selfieContent)) {
await bot.SendPhotoAsync(
123456,
stream,
"selfie with driver's license"
);
}
Translation File
A bot can request certified English translations of a document. Translations are also encrypted passport files so their decryption is no different from others passport files.
Assuming that the user sends one translation scan only for the license, we receive the translation passport file object in
message.passport_data.data[0].translation[0]
and its accompanying file credentials object in
credentials.secure_data.driver_license.translation[0]
.
File gets written to disk as a byte array.
PassportFile passportFile = element.Translation[0];
FileCredentials fileCreds = credentials.SecureData.DriverLicense.Translation[0];
// fetch passport file info
File encryptedFileInfo = await bot.GetFileAsync(passportFile.FileId);
// download encrypted file and get its bytes
byte[] encryptedContent;
using (System.IO.MemoryStream
stream = new System.IO.MemoryStream(encryptedFileInfo.FileSize)
)
{
await bot.DownloadFileAsync(encryptedFileInfo.FilePath, stream);
encryptedContent = stream.ToArray();
}
// decrypt the content and get bytes of the actual selfie photo
byte[] content = decrypter.DecryptFile(
encryptedContent,
fileCreds
);
// write the file to disk
await System.IO.File.WriteAllBytesAsync("/path/to/translation.jpg", content);