telegram-crawler/data/web/blogfork.telegram.org/passport.html
2024-04-22 11:05:10 +00:00

693 lines
34 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html class="">
<head>
<meta charset="utf-8">
<title>Telegram Passport Manual</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="description" content="Telegram Passport is a unified authorization method for services that require personal identification. Users can upload…">
<meta property="og:title" content="Telegram Passport Manual">
<meta property="og:image" content="390b421982e22447ad">
<meta property="og:description" content="Telegram Passport is a unified authorization method for services that require personal identification. Users can upload…">
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
<link href="/css/telegram.css?237" rel="stylesheet" media="screen">
<style>
</style>
</head>
<body class="preload">
<div class="dev_page_wrap">
<div class="dev_page_head navbar navbar-static-top navbar-tg">
<div class="navbar-inner">
<div class="container clearfix">
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
<ul class="nav navbar-nav">
<li><a href="//telegram.org/">Home</a></li>
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
<li class=""><a href="/api">API</a></li>
<li class=""><a href="/mtproto">Protocol</a></li>
<li class=""><a href="/schema">Schema</a></li>
</ul>
</div>
</div>
</div>
<div class="container clearfix">
<div class="dev_page">
<div id="dev_page_content_wrap" class=" ">
<div class="dev_page_bread_crumbs"></div>
<h1 id="dev_page_title">Telegram Passport Manual</h1>
<div id="dev_page_content"><!-- scroll_nav -->
<p><strong>Telegram Passport</strong> is a unified authorization method for services that require personal identification. Users can upload their documents once, then instantly share their data with services that require real-world ID (finance, ICOs, etc.). Telegram doesn't have access to the users' personal information thanks to end-to-end encryption.</p>
<h3><a class="anchor" href="#overview" id="overview" name="overview"><i class="anchor-icon"></i></a>Overview</h3>
<p>From the perspective of a service that requires real-world ID, the process looks like this:</p>
<ul>
<li>A user presses "Log in with Telegram" on your <strong>website</strong> or in your <strong>app</strong>.</li>
<li>You <a href="#requesting-information">request</a> the <a href="#fields">data</a> you need.</li>
<li>The user accepts your <a href="#privacy-policy">privacy policy</a> and agrees to share their data.</li>
<li>The user's Telegram app downloads and decrypts the data you requested from the end-to-end encrypted storage on Telegram.</li>
<li>If some of the data you requested is missing, the user can add it to their Telegram Passport at this point.</li>
<li>The user's app encrypts the data with your <a href="#generating-your-public-key">public key</a> and sends it to you.</li>
<li>You <a href="#decrypting-data">decrypt</a> the data, check it for <a href="#fixing-errors">errors</a> and re-request any missing or invalid information.</li>
<li>You sign the user up for your service. <strong>Tada!</strong></li>
</ul>
<p>Check out <a href="https://core.telegram.org/passport/example">this example</a> to see Telegram Passport in action.</p>
<blockquote>
<p>To learn more about Telegram Passport from the perspective of a user, please see <a href="https://telegram.org/blog/passport">this blog post</a> and the <a href="/api/passport">technical MTProto documentation</a>.
See <a href="/passport/encryption">this page</a> if you're interested in encryption algorithms used on Telegram's side.</p>
</blockquote>
<h3><a class="anchor" href="#recent-changes" id="recent-changes" name="recent-changes"><i class="anchor-icon"></i></a>Recent changes</h3>
<h4><a class="anchor" href="#august-25-2018" id="august-25-2018" name="august-25-2018"><i class="anchor-icon"></i></a>August 25, 2018</h4>
<p><strong>Telegram Passport 1.1</strong> (<a href="https://telegram.org/blog/export-and-more#improved-telegram-passport">blog post</a>)</p>
<ul>
<li>Added support for requesting <strong>several documents of one type</strong>. See the new objects <a href="#passportscope">PassportScope</a>, <a href="#passportscopeelement">PassportScopeElement</a>, <a href="#passportscopeelementone">PassportScopeElementOneOfSeveral</a> and <a href="#passportscopeelementone">PassportScopeElementOne</a>.</li>
<li>Added support for <strong>middle names</strong>.</li>
<li>Added support for requesting certified <strong>English translations</strong> for documents (see <a href="#fields">Fields</a>; new field <em>translation</em> also added to the <a href="#securevalue">SecureValue</a> object). <strong>Note:</strong> Please only request translations <em>after</em> you have received a valid document that requires one.</li>
<li>Added support for requesting <strong>names</strong> in the language of the user's country of residence (if other than English). New fields <em>first_name_native</em>, <em>last_name_native</em> and <em>middle_name_native</em> added to the <a href="#personaldetails">PersonalDetails</a> object.</li>
<li>Replaced the <em>payload</em> parameter with the new parameter <em>nonce</em>, which serves the same function, to make the purpose more obvious (see <a href="#request-parameters">Request Parameters</a> and the <a href="#credentials">Credentials</a> object).</li>
<li>Updated the <a href="/passport/example">example page</a> to support the new functionality.</li>
</ul>
<h3><a class="anchor" href="#setting-up-telegram-passport" id="setting-up-telegram-passport" name="setting-up-telegram-passport"><i class="anchor-icon"></i></a>Setting Up Telegram Passport</h3>
<p>To integrate Telegram Passport into your login or verification flow, you need a working Telegram bot (see <a href="/bots#how-do-i-create-a-bot">this page</a> for information on how to get one).</p>
<p>To request data from Telegram Passport users, your bot will need to generate a pair of encryption keys.</p>
<h4><a class="anchor" href="#generating-a-private-key" id="generating-a-private-key" name="generating-a-private-key"><i class="anchor-icon"></i></a>Generating a private key</h4>
<p>First, use a console to generate a <strong>private</strong> key:</p>
<pre><code>openssl genrsa 2048 &gt; private.key</code></pre>
<p><strong>WARNING: Keep your private key SECRET!</strong> </p>
<h4><a class="anchor" href="#generating-your-public-key" id="generating-your-public-key" name="generating-your-public-key"><i class="anchor-icon"></i></a>Generating your public key</h4>
<p>Then use the console to print the corresponding <strong>public</strong> key:</p>
<pre><code>openssl rsa -in private.key -pubout</code></pre>
<p>Use the <strong>/setpublickey</strong> command with <a href="https://t.me/BotFather">@BotFather</a> to connect this public key with your bot.</p>
<h4><a class="anchor" href="#privacy-policy" id="privacy-policy" name="privacy-policy"><i class="anchor-icon"></i></a>Privacy Policy</h4>
<p>Add a link to your Privacy Policy by using the <strong>/setprivacypolicy</strong> command. Users will see this link when offered to authorize you to access their data.</p>
<h3><a class="anchor" href="#requesting-information" id="requesting-information" name="requesting-information"><i class="anchor-icon"></i></a>Requesting Information</h3>
<h4><a class="anchor" href="#sdk" id="sdk" name="sdk"><i class="anchor-icon"></i></a>SDK</h4>
<p>To request information stored in a Telegram Passport, use one of these <strong>SDKs</strong>:</p>
<ul>
<li><a href="/passport/sdk-ios-mac">iOS/macOS SDK</a></li>
<li><a href="/passport/sdk-android">Android SDK</a></li>
<li><a href="/passport/sdk-javascript">Javascript SDK</a></li>
</ul>
<h4><a class="anchor" href="#request-parameters" id="request-parameters" name="request-parameters"><i class="anchor-icon"></i></a>Request Parameters</h4>
<p>Use the following parameters to request information with the SDK:</p>
<table class="table">
<tbody>
<tr>
<td><strong>Parameters</strong></td>
<td><strong>Type</strong></td>
<td><strong>Required</strong></td>
</tr>
<tr>
<td>bot_id</td>
<td>Integer</td>
<td>Yes</td>
</tr>
<tr>
<td>scope</td>
<td><a href="#passportscope">PassportScope</a></td>
<td>Yes</td>
</tr>
<tr>
<td>public_key</td>
<td>String</td>
<td>Yes</td>
</tr>
<tr>
<td>nonce</td>
<td>String</td>
<td>Yes</td>
</tr>
</tbody>
</table>
<h4><a class="anchor" href="#passportscope" id="passportscope" name="passportscope"><i class="anchor-icon"></i></a>PassportScope</h4>
<p>This object represents the data to be requested.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>data</td>
<td>Array of <a href="#passportscopeelement">PassportScopeElement</a></td>
<td>List of requested elements, each type may be used only once in the entire array of PassportScopeElement objects</td>
</tr>
<tr>
<td>v</td>
<td>Integer</td>
<td>Scope version, must be <em>1</em></td>
</tr>
</tbody>
</table>
<h4><a class="anchor" href="#passportscopeelement" id="passportscopeelement" name="passportscopeelement"><i class="anchor-icon"></i></a>PassportScopeElement</h4>
<p>This object represents a requested element, should be one of:</p>
<ul>
<li><a href="#passportscopeelementoneofseveral">PassportScopeElementOneOfSeveral</a> - use to request any one of the documents included in the scope.</li>
<li><a href="#passportscopeelementone">PassportScopeElementOne</a>  use to request one particular document.</li>
</ul>
<h4><a class="anchor" href="#passportscopeelementoneofseveral" id="passportscopeelementoneofseveral" name="passportscopeelementoneofseveral"><i class="anchor-icon"></i></a>PassportScopeElementOneOfSeveral</h4>
<p>This object represents several elements one of which must be provided.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>one_of</td>
<td>Array of <a href="#passportscopeelementone">PassportScopeElementOne</a></td>
<td>List of elements one of which must be provided; must contain either several of “passport”, “driver_license”, “identity_card”, “internal_passport” <strong>or</strong> several of “utility_bill”, “bank_statement”, “rental_agreement”, “passport_registration”, “temporary_registration”</td>
</tr>
<tr>
<td>selfie</td>
<td>Boolean</td>
<td><em>Optional.</em> Use this parameter if you want to request a selfie with the document from this list that the user chooses to upload.</td>
</tr>
<tr>
<td>translation</td>
<td>Boolean</td>
<td><em>Optional.</em> Use this parameter if you want to request a translation of the document from this list that the user chooses to upload. <strong>Note:</strong> We suggest to only request translations <em>after</em> you have received a valid document that requires one.</td>
</tr>
</tbody>
</table>
<h4><a class="anchor" href="#passportscopeelementone" id="passportscopeelementone" name="passportscopeelementone"><i class="anchor-icon"></i></a>PassportScopeElementOne</h4>
<p>This object represents one particular element that must be provided. If no options are needed, <em>String</em> can be used instead of this object to specify the type of the element.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>type</td>
<td>String</td>
<td>Element type. One of "personal_details", "passport", "driver_license", "identity_card", "internal_passport", "address", "utility_bill", "bank_statement", "rental_agreement", "passport_registration", "temporary_registration", "phone_number", "email"</td>
</tr>
<tr>
<td>selfie</td>
<td>Boolean</td>
<td><em>Optional.</em> Use this parameter if you want to request a selfie with the document as well. Available for "passport", "driver_license", "identity_card" and "internal_passport"</td>
</tr>
<tr>
<td>translation</td>
<td>Boolean</td>
<td><em>Optional.</em> Use this parameter if you want to request a translation of the document as well. Available for "passport", "driver_license", "identity_card", "internal_passport", "utility_bill", "bank_statement", "rental_agreement", "passport_registration" and "temporary_registration". <strong>Note:</strong> We suggest to only request translations <em>after</em> you have received a valid document that requires one.</td>
</tr>
<tr>
<td>native_names</td>
<td>Boolean</td>
<td><em>Optional.</em> Use this parameter to request the first, last and middle name of the user in the language of the user's country of residence. Available for "personal_details"</td>
</tr>
</tbody>
</table>
<p>You can also use the special type "id_document" as an alias for one of "passport", "driver_license", "identity_card" and the special type "address_document" as an alias for one of "utility_bill", "bank_statement", "rental_agreement".
So <code>{"type":"id_document",selfie:true}</code> is equal to <code>{"one_of":["passport","driver_license","identity_card"],selfie:true}</code>.</p>
<h4><a class="anchor" href="#fields" id="fields" name="fields"><i class="anchor-icon"></i></a>Fields</h4>
<p>Your bot can request personal details, one or several types of identity document, residential address, one or several types of proof of address document, a phone number, or an email address. You can also request optional <strong>selfies</strong> with the document and certified <strong>English translations</strong> of the document.
This is just a list of data types that can be requested, and the encrypted objects that will contain such data.</p>
<blockquote>
<p><strong>Note:</strong> We suggest to only request English translations <em>after</em> you have received a valid document that requires one.</p>
</blockquote>
<div><table class="table">
<thead>
<tr><th>Name</th><th>Key</th><th>Type</th><th>Description</th></tr>
</thead>
<tbody>
<tr><td>personal_details</td><td>data</td><td><a href="#personaldetails">PersonalDetails</a></td><td>Personal Details</td></tr>
<tr><td rowspan="4">passport</td><td>data</td><td><a href="#iddocumentdata">IdDocumentData</a></td><td rowspan="4">Passport</td></tr>
<tr><td>front_side</td><td><a href="#passportfile">PassportFile</a></td></tr>
<tr><td>selfie</td><td><i>Optional.</i> <a href="#passportfile">PassportFile</a></td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td rowspan="4">internal_passport</td><td>data</td><td><a href="#iddocumentdata">IdDocumentData</a></td><td rowspan="4">Internal Passport</td></tr>
<tr><td>front_side</td><td><a href="#passportfile">PassportFile</a></td></tr>
<tr><td>selfie</td><td><i>Optional.</i> <a href="#passportfile">PassportFile</a></td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td rowspan="5">driver_license</td><td>data</td><td><a href="#iddocumentdata">IdDocumentData</a></td><td rowspan="5">Driver License</td></tr>
<tr><td>front_side</td><td><a href="#passportfile">PassportFile</a></td></tr>
<tr><td>reverse_side</td><td><a href="#passportfile">PassportFile</a></td></tr>
<tr><td>selfie</td><td><i>Optional.</i> <a href="#passportfile">PassportFile</a></td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td rowspan="5">identity_card</td><td>data</td><td><a href="#iddocumentdata">IdDocumentData</a></td><td rowspan="5">Identity Card</td></tr>
<tr><td>front_side</td><td><a href="#passportfile">PassportFile</a></td></tr>
<tr><td>reverse_side</td><td><a href="#passportfile">PassportFile</a></td></tr>
<tr><td>selfie</td><td><i>Optional.</i> <a href="#passportfile">PassportFile</a></td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td>address</td><td>data</td><td><a href="#residentialaddress">ResidentialAddress</a></td><td>Address</td></tr>
<tr><td rowspan="2">utility_bill</td><td>files</td><td>Array of <a href="#passportfile">PassportFile</a></td><td rowspan="2">Utility Bill</td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td rowspan="2">bank_statement</td><td>files</td><td>Array of <a href="#passportfile">PassportFile</a></td><td rowspan="2">Bank Statement</td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td rowspan="2">rental_agreement</td><td>files</td><td>Array of <a href="#passportfile">PassportFile</a></td><td rowspan="2">Rental Agreement</td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td rowspan="2">passport_registration</td><td>files</td><td>Array of <a href="#passportfile">PassportFile</a></td><td rowspan="2">Registration Page in the Internal Passport</td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td rowspan="2">temporary_registration</td><td>files</td><td>Array of <a href="#passportfile">PassportFile</a></td><td rowspan="2">Temporary Registration</td></tr>
<tr><td>translation</td><td><i>Optional.</i> Array of <a href="#passportfile">PassportFile</a></td></tr>
<tr><td>phone_number</td><td></td><td>String</td><td>Phone number</td></tr>
<tr><td>email</td><td></td><td>String</td><td>Email</td></tr>
</tbody>
</table></div>
<h4><a class="anchor" href="#personaldetails" id="personaldetails" name="personaldetails"><i class="anchor-icon"></i></a>PersonalDetails</h4>
<p>This object represents personal details.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>first_name</td>
<td>String</td>
<td>First Name</td>
</tr>
<tr>
<td>last_name</td>
<td>String</td>
<td>Last Name</td>
</tr>
<tr>
<td>middle_name</td>
<td>String</td>
<td><em>Optional.</em> Middle Name</td>
</tr>
<tr>
<td>birth_date</td>
<td>String</td>
<td>Date of birth in DD.MM.YYYY format</td>
</tr>
<tr>
<td>gender</td>
<td>String</td>
<td>Gender, <em>male</em> or <em>female</em></td>
</tr>
<tr>
<td>country_code</td>
<td>String</td>
<td>Citizenship (ISO 3166-1 alpha-2 country code)</td>
</tr>
<tr>
<td>residence_country_code</td>
<td>String</td>
<td>Country of residence (ISO 3166-1 alpha-2 country code)</td>
</tr>
<tr>
<td>first_name_native</td>
<td>String</td>
<td>First Name in the language of the user's country of residence</td>
</tr>
<tr>
<td>last_name_native</td>
<td>String</td>
<td>Last Name in the language of the user's country of residence</td>
</tr>
<tr>
<td>middle_name_native</td>
<td>String</td>
<td><em>Optional.</em> Middle Name in the language of the user's country of residence</td>
</tr>
</tbody>
</table>
<h4><a class="anchor" href="#residentialaddress" id="residentialaddress" name="residentialaddress"><i class="anchor-icon"></i></a>ResidentialAddress</h4>
<p>This object represents a residential address.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>street_line1</td>
<td>String</td>
<td>First line for the address</td>
</tr>
<tr>
<td>street_line2</td>
<td>String</td>
<td><em>Optional.</em> Second line for the address</td>
</tr>
<tr>
<td>city</td>
<td>String</td>
<td>City</td>
</tr>
<tr>
<td>state</td>
<td>String</td>
<td><em>Optional.</em> State</td>
</tr>
<tr>
<td>country_code</td>
<td>String</td>
<td>ISO 3166-1 alpha-2 country code</td>
</tr>
<tr>
<td>post_code</td>
<td>String</td>
<td>Address post code</td>
</tr>
</tbody>
</table>
<h4><a class="anchor" href="#iddocumentdata" id="iddocumentdata" name="iddocumentdata"><i class="anchor-icon"></i></a>IdDocumentData</h4>
<p>This object represents the data of an identity document.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>document_no</td>
<td>String</td>
<td>Document number</td>
</tr>
<tr>
<td>expiry_date</td>
<td>String</td>
<td><em>Optional.</em> Date of expiry, in DD.MM.YYYY format</td>
</tr>
</tbody>
</table>
<h4><a class="anchor" href="#passportfile" id="passportfile" name="passportfile"><i class="anchor-icon"></i></a>PassportFile</h4>
<p>This object represents a <a href="/bots/api#passportfile">PassportFile</a> related to a document. The file is up to 10 MB in size and in the .jpg format.</p>
<h3><a class="anchor" href="#receiving-information" id="receiving-information" name="receiving-information"><i class="anchor-icon"></i></a>Receiving information</h3>
<p>When the user confirms your request by pressing the "Authorize" button, the Bot API sends an <a href="/bots/api#update">Update</a> with the field <em>passport_data</em> to the bot that contains encrypted <a href="/bots/api#passportdata">Telegram Passport data</a>.</p>
<blockquote>
<p>Note that all base64-encoded fields should be decoded before use.</p>
</blockquote>
<h4><a class="anchor" href="#decrypting-data" id="decrypting-data" name="decrypting-data"><i class="anchor-icon"></i></a>Decrypting data</h4>
<p>To decrypt the received data, first, decrypt the credentials contained in <a href="/bots/api#encryptedcredentials">EncryptedCredentials</a>.</p>
<ol>
<li>
<p>Decrypt the credentials secret ( <em>secret</em> field in <a href="/bots/api#encryptedcredentials">EncryptedCredentials</a>) using your <strong>private</strong> key (set OAEP padding option, e.g. <code>OPENSSL_PKCS1_OAEP_PADDING</code> in PHP)</p>
</li>
<li>
<p>Use this secret and the credentials hash ( <em>hash</em> field in <a href="/bots/api#encryptedcredentials">EncryptedCredentials</a>) to calculate <em>credentials_key</em> and <em>credentials_iv</em> as described below:</p>
<pre><code> credentials_secret_hash = SHA512( credentials_secret + credentials_hash )
credentials_key = slice( credentials_secret_hash, 0, 32 )
credentials_iv = slice( credentials_secret_hash, 32, 16 )</code></pre>
</li>
<li>
<p>Decrypt the credentials data ( <em>data</em> field in <a href="/bots/api#encryptedcredentials">EncryptedCredentials</a>) by AES256-CBC using these <em>credentials_key</em> and <em>credentials_iv</em>. <strong>IMPORTANT:</strong> At this step, make sure that the credentials hash is equal to <code>SHA256( credentials_data )</code></p>
</li>
<li>
<p>Credentials data is padded with 32 to 255 random padding bytes to make its length divisible by 16 bytes. The first byte contains the length of this padding (including this byte). Remove the padding to get the data.</p>
</li>
</ol>
<blockquote>
<p>Note that all hashes represent as raw binary data, not hexits</p>
</blockquote>
<h4><a class="anchor" href="#credentials" id="credentials" name="credentials"><i class="anchor-icon"></i></a>Credentials</h4>
<p>Credentials is a JSON-serialized object.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>secure_data</td>
<td><a href="#securedata">SecureData</a></td>
<td>Credentials for encrypted data</td>
</tr>
<tr>
<td>nonce</td>
<td>String</td>
<td>Bot-specified nonce</td>
</tr>
</tbody>
</table>
<p><strong>IMPORTANT:</strong> Make sure that the <strong>nonce</strong> is the same as was passed in the request.</p>
<h4><a class="anchor" href="#securedata" id="securedata" name="securedata"><i class="anchor-icon"></i></a>SecureData</h4>
<p>This object represents the credentials required to decrypt encrypted data. All fields are optional and depend on <a href="#fields">fields</a> that were requested.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>personal_details</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted personal details</td>
</tr>
<tr>
<td>passport</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted passport</td>
</tr>
<tr>
<td>internal_passport</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted internal passport</td>
</tr>
<tr>
<td>driver_license</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted driver license</td>
</tr>
<tr>
<td>identity_card</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted ID card</td>
</tr>
<tr>
<td>address</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted residential address</td>
</tr>
<tr>
<td>utility_bill</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted utility bill</td>
</tr>
<tr>
<td>bank_statement</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted bank statement</td>
</tr>
<tr>
<td>rental_agreement</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted rental agreement</td>
</tr>
<tr>
<td>passport_registration</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted registration from internal passport</td>
</tr>
<tr>
<td>temporary_registration</td>
<td><a href="#securevalue">SecureValue</a></td>
<td><em>Optional.</em> Credentials for encrypted temporary registration</td>
</tr>
</tbody>
</table>
<h4><a class="anchor" href="#securevalue" id="securevalue" name="securevalue"><i class="anchor-icon"></i></a>SecureValue</h4>
<p>This object represents the credentials required to decrypt encrypted values. All fields are optional and depend on the type of <a href="#fields">fields</a> that were requested.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>data</td>
<td><a href="#datacredentials">DataCredentials</a></td>
<td><em>Optional.</em> Credentials for encrypted Telegram Passport data. Available for "personal_details", "passport", "driver_license", "identity_card", "internal_passport" and "address" types.</td>
</tr>
<tr>
<td>front_side</td>
<td><a href="#filecredentials">FileCredentials</a></td>
<td><em>Optional.</em> Credentials for an encrypted document's front side. Available for "passport", "driver_license", "identity_card" and "internal_passport".</td>
</tr>
<tr>
<td>reverse_side</td>
<td><a href="#filecredentials">FileCredentials</a></td>
<td><em>Optional.</em> Credentials for an encrypted document's reverse side. Available for "driver_license" and "identity_card".</td>
</tr>
<tr>
<td>selfie</td>
<td><a href="#filecredentials">FileCredentials</a></td>
<td><em>Optional.</em> Credentials for an encrypted selfie of the user with a document. Available for "passport", "driver_license", "identity_card" and "internal_passport".</td>
</tr>
<tr>
<td>translation</td>
<td>Array of <a href="#filecredentials">FileCredentials</a></td>
<td><em>Optional.</em> Credentials for an encrypted translation of the document. Available for "passport", "driver_license", "identity_card", "internal_passport", "utility_bill", "bank_statement", "rental_agreement", "passport_registration" and "temporary_registration".</td>
</tr>
<tr>
<td>files</td>
<td>Array of <a href="#filecredentials">FileCredentials</a></td>
<td><em>Optional.</em> Credentials for encrypted files. Available for "utility_bill", "bank_statement", "rental_agreement", "passport_registration" and "temporary_registration" types.</td>
</tr>
</tbody>
</table>
<h4><a class="anchor" href="#datacredentials" id="datacredentials" name="datacredentials"><i class="anchor-icon"></i></a>DataCredentials</h4>
<p>These credentials can be used to decrypt encrypted data from the <em>data</em> field in <a href="/bots/api#encryptedpassportelement">EncryptedPassportElement</a>.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>data_hash</td>
<td>String</td>
<td>Checksum of encrypted data</td>
</tr>
<tr>
<td>secret</td>
<td>String</td>
<td>Secret of encrypted data</td>
</tr>
</tbody>
</table>
<ol>
<li>
<p>To decrypt data, use the corresponding secret and data_hash from <a href="#datacredentials">DataCredentials</a> as described below:</p>
<pre><code> data_secret_hash = SHA512( data_secret + data_hash )
data_key = slice( data_secret_hash, 0, 32 )
data_iv = slice( data_secret_hash, 32, 16 )</code></pre>
</li>
<li>
<p>Use AES256-CBC with this <em>data_key</em> and <em>data_iv</em> to decrypt the data (the <em>data</em> field in <a href="/bots/api#encryptedpassportelement">EncryptedPassportElement</a>). <strong>IMPORTANT:</strong> At this step, make sure that data_hash from the credentials is equal to <code>SHA256( data )</code>.</p>
</li>
<li>
<p>The data is padded with 32 to 255 random padding bytes to make its length divisible by 16 bytes. The first byte contains the length of the padding (including this byte). Remove padding to get the data.</p>
</li>
<li>
<p>The data is a JSON-serialized object of one of the following types: <a href="#personaldetails">PersonalDetails</a>, <a href="#iddocumentdata">IdDocumentData</a>, <a href="#residentialaddress">ResidentialAddress</a>, depending on <a href="#fields">type</a>.</p>
</li>
</ol>
<h4><a class="anchor" href="#filecredentials" id="filecredentials" name="filecredentials"><i class="anchor-icon"></i></a>FileCredentials</h4>
<p>These credentials can be used to decrypt encrypted files from the <em>front_side</em>, <em>reverse_side</em>, <em>selfie</em>, <em>files</em> and <em>translation</em> fields in <a href="/bots/api#encryptedpassportelement">EncryptedPassportElement</a>.</p>
<table class="table">
<tbody>
<tr>
<td><strong>Field</strong></td>
<td><strong>Type</strong></td>
<td><strong>Description</strong></td>
</tr>
<tr>
<td>file_hash</td>
<td>String</td>
<td>Checksum of encrypted file</td>
</tr>
<tr>
<td>secret</td>
<td>String</td>
<td>Secret of encrypted file</td>
</tr>
</tbody>
</table>
<ol>
<li>
<p>To decrypt the file, use the corresponding secret and file_hash from <a href="#filecredentials">FileCredentials</a> as described below:</p>
<pre><code> file_secret_hash = SHA512( file_secret + file_hash )
file_key = slice( file_secret_hash, 0, 32 )
file_iv = slice( file_secret_hash, 32, 16 )</code></pre>
</li>
<li>
<p>Download the encrypted file using the <a href="/bots/api#getfile">getFile</a> method.</p>
</li>
<li>
<p>Use AES256-CBC with this <em>file_key</em> and <em>file_iv</em> to decrypt the content of the file. <strong>IMPORTANT:</strong> At this step, make sure that file_hash from the credentials is equal to <code>SHA256( file_content )</code>.</p>
</li>
<li>
<p>The content of the file is padded with 32 to 255 random padding bytes to make its length divisible by 16 bytes. The first byte contains the length of the padding (including that byte). Remove padding to get the file content.</p>
</li>
</ol>
<h3><a class="anchor" href="#fixing-errors" id="fixing-errors" name="fixing-errors"><i class="anchor-icon"></i></a>Fixing errors</h3>
<p>If the data you received contains errors, the bot can use the <a href="/bots/api#setpassportdataerrors">setPassportDataErrors</a> method to inform the user and <a href="#requesting-information">request information</a> again. The user will not be able to resend the data, until all errors are fixed.</p></div>
</div>
</div>
</div>
<div class="footer_wrap">
<div class="footer_columns_wrap footer_desktop">
<div class="footer_column footer_column_telegram">
<h5>Telegram</h5>
<div class="footer_telegram_description"></div>
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
</div>
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
<ul>
<li><a href="//telegram.org/faq">FAQ</a></li>
<li><a href="//telegram.org/privacy">Privacy</a></li>
<li><a href="//telegram.org/press">Press</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
<ul>
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
<li><a href="//telegram.org/android">Android</a></li>
<li><a href="//telegram.org/dl/web">Mobile Web</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
<ul>
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
<li><a href="//macos.telegram.org/">macOS</a></li>
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
</ul>
</div>
<div class="footer_column footer_column_platform">
<h5><a href="/">Platform</a></h5>
<ul>
<li><a href="/api">API</a></li>
<li><a href="//translations.telegram.org/">Translations</a></li>
<li><a href="//instantview.telegram.org/">Instant View</a></li>
</ul>
</div>
</div>
<div class="footer_columns_wrap footer_mobile">
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/blog">Blog</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps">Apps</a></h5>
</div>
<div class="footer_column">
<h5><a href="/">Platform</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/press">Press</a></h5>
</div>
</div>
</div>
</div>
<script src="/js/main.js?47"></script>
<script src="/js/jquery.min.js?1"></script>
<script src="/js/bootstrap.min.js?1"></script>
<script>window.initDevPageNav&&initDevPageNav();
backToTopInit("Go up");
removePreloadInit();
</script>
</body>
</html>