How to sign the URL scheme by an access key
To ensure that your app or site users launch Yandex Maps mobile app without limitations:
-
Get an access-key. To do this, fill in the form.
-
Use the following URL format:
yandexmaps://maps.yandex.com/?{parameters}&client=<client ID>&signature=<signature>
- client
- The client ID you have got with the key. Even if you have multiple apps, you only need one ID.
- signature
- Signature is a string to be generated from the source URL using an access key.
How to generate a signed URL
-
Compose a URL corresponding to the task for the app to perform. The following URL lets you show a point on the map:
yandexmaps://maps.yandex.ru?ll=55.75,37.64&z=14
-
Add the
client
parameter to the URL, enter the following identifier as its value:yandexmaps://maps.yandex.ru?ll=55.75,37.64&z=14&client=007
-
Calculate a hash sum from the URL resulting from the previous step using SHA-256 hash function. Then use the access key to encrypt the resulting hash sum.
The access key is an RSA key you have received after the registration. Physically, it is a record in a text file. The file can have a name, e.g.,
key.pem
.Below is an example of encryption using the OpenSSL utility.
Bash
$ echo -n 'yandexmaps://maps.yandex.ru?ll=55.75,37.64&z=14&client=007' | openssl dgst -sha256 -sign key.pem | base64 | tr -d '\n' | python -c "import urllib, sys; print urllib.quote(sys.stdin.read(), safe='')"
-
Generate a US-ASCII signature string.
To send binary data in a URL, you should recode them to the US-ASCII character set. Therefore, first use base64 representation to convert your binary data to an ASCII string. Then convert the resulting string to US-ASCII via URL encoding.
Python
from Crypto.PublicKey import RSA from Crypto.Hash import SHA256 from Crypto.Signature import PKCS1_v1_5 from base64 import b64encode from urllib import quote print "sign" with open("key.pem") as f: private_key = RSA.importKey(f.read()) h = SHA256.new(src_data) print "hash value" print h.hexdigest() signer = PKCS1_v1_5.new(private_key) signature = quote(b64encode(signer.sign(h)), safe='')
-
Use the string resulting from the previous step as the
signature
parameter value. Example of a signed URL:yandexmaps://maps.yandex.ru?ll=55.75,37.64&z=14&client=007&signature=JYEYuBc7154%2Be%2BHHW8RKG0O2dVx%2B%2B...
How to convert an RSA key
We generate RSA keys in PEM format (PKCS1 standard). Other formats have also been adopted in mobile operating systems. To ensure compatibility, convert the key.
Conversion examples using the OpenSSL utility are given below.
Conversion of a text file in the PEM format to a binary DER file. As a result, we get a key in the DER format (PKCS1 standard):
$ openssl rsa -in key.pem -out key.der -outform DER
Conversion of a PKCS1 PEM key to a PKCS8 key:
$ openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in key-pkcs1.pem -out key-pkcs8.pem
Conversion of a PEM PKCS1 key to a DER key (PKCS8 standard):
$ openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt -in key-pkcs1.pem -out key-pkcs8.pem
$ openssl pkcs8 -topk8 -inform PEM -outform DER -in key-pkcs8.pem -out key.der -nocrypt
Examples of native application code
import android.content.Intent;
import android.net.Uri;
import android.util.Base64;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
public class YaMapsStarter {
private final String PRIVATE_KEY;
// Generates a record using the key.
public String sha256rsa(String key, String data) throws SecurityException {
String trimmedKey = key.replaceAll("-----\\w+ PRIVATE KEY-----", "")
.replaceAll("\\s", "");
try {
byte[] result = Base64.decode(trimmedKey, Base64.DEFAULT);
KeyFactory factory = KeyFactory.getInstance("RSA");
EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(result);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(factory.generatePrivate(keySpec));
signature.update(data.getBytes());
byte[] encrypted = signature.sign();
return Base64.encodeToString(encrypted, Base64.NO_WRAP);
} catch (Exception e) {
throw new SecurityException("Error calculating cipher data. SIC!");
}
}
// Generates a signed URI and starts Yandex Maps.
public void openMap() {
Uri uri = Uri.parse("yandexmaps://maps.yandex.ru").buildUpon()
.appendQueryParameter("ll", 55.75,37.64)
.appendQueryParameter("z", "14")
.appendQueryParameter("client", "007").build();
uri = uri.buildUpon()
.appendQueryParameter("signature", sha256rsa(PRIVATE_KEY, uri.toString()))
.build();
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setPackage("ru.yandex.yandexmaps");
startActivity(intent);
}
}
The client ID you have got with the key. Even if you have multiple apps, you only need one ID.
The access key is an RSA key you have received after the registration. Physically, it is a record in a text file. The file can have a name, e.g., key.pem
.
The client ID you have got with the key. Even if you have multiple apps, you only need one ID.
Signature is a string to be generated from the source URL using an access key.
The client ID you have got with the key. Even if you have multiple apps, you only need one ID.
Signature is a string to be generated from the source URL using an access key.