Flutter and GOST TLS
My name is Andriy Kupriev, I am a Flutter developer in the team of the Center for the Development of Financial Technologies (TCFT) of Rossilhospbank. In this article, we will consider how to implement GOST TLS protocol support in applications developed on Flutter.
Flutter, with its attractive cross-platform design, has won the hearts of mobile app developers. However, in areas where data privacy is paramount, application security becomes a top priority. And certain requirements of using domestic cryptographic algorithms in the field of confidentiality and integrity make this task very non-trivial and exciting for a Flutter developer. We will talk about this in more detail in the article.
Contents
- 1 TLS: A brief overview
- 2 What is GOST TLS
- 3 What standards are used in GOST TLS?
- 4 What does the GOST TLS implementation look like for Android
- 5 Algorithms supported by Crypto About CSP
- 6 What does the GOST TLS implementation look like under iOS using Crypto About CSP
- 7 And what about Flutter?
- 8 Conclusion
TLS: A brief overview
The TLS (Transport Layer Security) protocol is one of the most widely used mechanisms for establishing a secure communication channel. Based on the SSL (Secure Sockets Layer) specification version 3.0, TLS has undergone significant changes during its development. TLS 1.3 is currently the current version, although TLS 1.2 remains the most widely used.
The main task of TLS is to create a secure channel between the client and the server to guarantee the integrity and confidentiality of the transmitted data. The protocol uses different cryptographic algorithms at different stages of its work. These algorithms are defined by a cryptoset, which is a collection of algorithms defined in standardization documents. The parties agree on the crypto set at the beginning of the installation of the secure channel.
What is GOST TLS
GOST TLS uses Russian cryptographic algorithms within the cryptographic sets of the TLS protocol.
In the context of cryptography, the abbreviation “GOST” is used to denote Russian state cryptographic standards. These standards define algorithms for encryption, hashing, electronic signatures and other cryptography methods used in Russia to ensure information security.
STATE STANDARD TLS is designed to create a secure network connection when processing information that does not contain confidential data included in state secrets.
What standards are used in GOST TLS?
-
GOST R 34.10–2012 The standard defines algorithms for the formation and verification of an electronic digital signature. These algorithms are used to authenticate and sign messages. (ISO 2382-2 [1]ISO/MEC 9796 [2]‑[3]ISO/MEC 14,888 [4]‑[7] and ISO/MEC 10 118 series [8]‑[11]).
-
GOST R 34.11–2012 The standard defines hashing algorithms. These algorithms are used to create hashes of the data and ensure the integrity of the messages being transmitted. (ISO 2382-2 [1]ISO/MEC 9796 [2–3]series ISO/MEC 14 888 [4–7] and ISO/MEC 10 118 series [8–11]).
-
GOST R 34.12–2015 The standard defines block encryption algorithms, including GOST 34.12–2015/256, GOST 34.12–2015/512. These algorithms are used for data encryption in GOST TLS. (ISO/MEC 10116 and ISO/MEC 18033 series).
-
GOST R 34.13–2015 The standard defines the mode of operation of block ciphers. These modes of operation of block ciphers determine the rules of cryptographic transformation of data and production of imitation rates for messages of arbitrary size. (ISO/MEC 9797-1 [1]ISO/MEC 10 116 [2]ISO/MEC 10 118–1 [3]ISO/MEC 18 033 [4]ISO/MEC 14 888-1 [5]).
These standards are key components of GOST TLS and provide the cryptographic operations required for authentication, encryption and data integrity within this protocol.
What does the GOST TLS implementation look like for Android
In the case of Android, it is possible to use crypto providers, for example, from the company Krypto Pro (Krypto Pro CSP), which supplies the implementation of GOST algorithms. Thanks to the JCA (Java Cryptography Architecture), this crypto provider can be freely integrated for use in TLS.
When establishing a connection, there are two ways to define authentication parameters, using dynamic or static SSLContext (using System.setProperty and javax.net.ssl.* parameters).
SSLContext is part of JSSE (Java Secure Socket Extension). SSLContext is a core class in JSSE that is used to create and configure SSL/TLS sessions. This class allows applications to manage security settings such as encryption protocols, certificates, and authentication options.
As such, SSLContext is a key component of JSSE that provides the foundation for secure Java networking. JSSE generally provides a set of APIs for implementing socket security, and SSLContext is the primary tool for creating and managing SSL/TLS connections in Java applications.
The static context is set once per entire java process, and is optional, here is an example setting:
Security.setProperty("ssl.KeyManagerFactory.algorithm", "GostX509"); // ГОСТ алгоритм
Security.setProperty("ssl.TrustManagerFactory.algorithm", "GostX509"); // ГОСТ алгоритм
Security.setProperty("ssl.SocketFactory.provider", "ru.CryptoPro.ssl.SSLSocketFactoryImpl"); // задаем реализацию сокетов с ГОСТ алгоритмами
Security.setProperty("ssl.ServerSocketFactory.provider", "ru.CryptoPro.ssl.SSLServerSocketFactoryImpl"); // задаем реализацию сокетов сервера с ГОСТ алгоритмами
System.setProperty("javax.net.ssl.trustStore", "path_to_trust_store"); // хранилище сертификатов
System.setProperty("javax.net.ssl.trustStoreType", "CertStore"); // может быть другой тип
System.setProperty("javax.net.ssl.trustStoreProvider", "JCP"); // может быть другой провайдер
System.setProperty("javax.net.ssl.trustStorePassword", "password_to_trust_store");
System.setProperty("javax.net.ssl.keyStore", ""); // тут может быть алиас ключа
System.setProperty("javax.net.ssl.keyStoreType", "HDIMAGE"); // может быть другой тип
System.setProperty("javax.net.ssl.keyStoreProvider", "JCSP"); // может быть другой провайдер
System.setProperty("javax.net.ssl.keyStorePassword", "password_to_key"); // пароль к ключу
System.setProperty("ngate_set_jcsp_if_gost", "true"); // для работы в режиме Knox на Samsung задаем провайдер Java CSP в качестве провайдера по умолчанию
The dynamic context is created without the participation of settings from the javax.net.ssl.* group, only with the help of classes of the javax.net.ssl.* package, for example:
KeyStore ts = KeyStore.getInstance("CertStore", "JCP");
ts.load("trust_store_stream", "trust_store_password"); // хранилище корневых сертификатов
KeyManagerFactory kmf = KeyManagerFactory.getInstance("GostX509", "JTLS");
if (isClientAuth) { // если требуется клиентская аутентификация
// параметры хранилища ключей клиента
KeyStore ks = KeyStore.getInstance("HDIMAGE", "JCSP");
// явное указание контейнера
if (haveKeyAlias) { // можно ли указать алиас?
ks.load(new StoreInputStream("key_alias"), null); // алиас ключа
} // if
else {
ks.load(null, null);
} // else
kmf.init(ks, password_to_key); // пароль к ключу
} // if
TrustManagerFactory tmf = TrustManagerFactory.getInstance("GostX509", "JTLS");
tmf.init(ts);
SSLContext context = SSLContext.getInstance("GostTLSv1.2", "JTLS"); // протокол TLS v.1.2
context.init(isClientAuth ? kmf.getKeyManagers() : null, tmf.getTrustManagers(), null);
The created context can then be passed to a suitable https connection implementation, such as HttpsURLConnection, OkHttp, Apache Http Client 5, and others. All these libraries accept an SSLContext object in different ways, although the most common way is to pass an SSLSocketFactory object derived from SSLContext.
The main difference between these methods is that if, for example, after setting a static context in the first case, you try to contact a server that does not support GOST TLS, then you will not be able to establish a connection. This can be done using the second method. You can configure the network clients of your libraries and use one network client configured for a GOST TLS connection and another for a regular TLS connection.
First, in order to use Crypto Pro CSP in your Android application, you need to connect, configure and initialize it. Place the library files in the libs folder, link and configure them in build.gradle, and initialize them by calling the CSPConfig.init(this) method.
The init() method performs the initial configuration of the provider in the context of the application, including creating directories, copying and verifying license and configuration files, as well as creating a trusted BKS repository in the application’s Security folder and other necessary actions
A detailed description of this process can be found in the Crypto About CSP guide.
Algorithms supported by Crypto About CSP
-
Electronic signature: GOST R 34.10-2012 (GOST 34.10-2018), ECDSA, RSA.
-
Hash functions: GOST R 34.11-2012 (GOST 34.11-2018), SHA-1, SHA-2.
-
Encryption: GOST R 34.12–2015 (GOST 34.12–2018), GOST R 34.13–2015 (GOST 34.13–2018), GOST 28 147–89, AES (128/192/256), DES, 2, RC4.
What does the GOST TLS implementation look like under iOS using Crypto About CSP
To provide GOST TLS support under iOS using Crypto Pro CSP, it is suggested to use its implementation of the libcurl library. This library is a tool for working with the network, and its integration with Crypto Pro CSP allows interaction with the GOST TLS protocol.
The libcurl library undertakes the main tasks related to the operation of the GOST TLS protocol. To send requests to the network, we need to form a curl request and send it, and then process the response we receive.
To specify the use of GOST TLS for libcurl from Crypto About CSP, certain options must be set:
curl_easy_setopt(curlHandle, CURLOPT_STRICT_GOST, 1L);
curl_easy_setopt(curlHandle, CURLOPT_NOPROXY, "*");
curl_easy_setopt(curlHandle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS);
curl_easy_setopt(curlHandle, CURLOPT_SSL_VERIFYPEER, 1);
These options allow you to configure libcurl to use GOST TLS.
In general, the implementation of GOST TLS under iOS using Crypto Pro CSP looks as follows:
We connect the Crypto About CSP library to the iOS application. (The integration process is described in detail in the documentation).
We create an implementation of sending a network request through libcurl taking into account GOST TLS.
We’re building a Swift/Objective-C API to make this query easy to use in an iOS app.
And what about Flutter?
And Flutter together with Dart do not know anything about GOST algorithms, they do not know about these standards and protocols. Therefore, they cannot use them anywhere by default. In addition, Dart/Flutter does not have a crypto architecture like JCA (Java Cryptography Architecture), where we could use our crypto provider, which provides an implementation of GOST algorithms, by connecting which we could use these algorithms.
A possible option for using GOST TLS Flutter is a native implementation of GOST TLS separately on Android and separately on IOS, using platform channels for two-way data transfer conditionally from Flutter/Dart to Android (Java, Kotlin) and IOS (Swift/Objective-C).
Actually, for internal use in our projects, we went this way. On the way to creating a plugin. Implemented GOST TLS implementation on Android and IOS. With the help of platform channels, two-way data transfer was implemented. For ease of implementation in any projects, we have created an implementation of our http client and Dio adapter. As a result, it was possible to reduce the connection of the library and the implementation of GOST TLS in your project to a few lines of code. This is connecting the plugin dependencies in the project’s pubspec.yml, and connecting the Dio adapter to our Dio client.
There are quite a few packages in the Flutter/Dart ecosystem that accept http network clients as input. So, in this case, these packets start using GOST TLS in themselves, without even noticing it, thanks to the use of the “guest” http client implemented in the plugin. This, for example, happened to us with the matrix_api_lite package that we use for our internal corporate messenger. We simply transferred our http client from the plugin to the MatrixApi constructor (well, its implementation allowed it), and it started working according to GOST TLS without any modifications or forks.
Conclusion
Recently, Flutter, as a solution for cross-platform development, is increasingly penetrating even in quite conservative directions. And as practice has shown, the flexibility of this technology allows you to successfully cope with almost any challenges.