avatarProf Bill Buchanan OBE

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

5644

Abstract

umber">753576475</span>A<span class="hljs-number">382</span>F<span class="hljs-number">32685733343333446</span>B<span class="hljs-number">3163667738636139303059644831764</span>A<span class="hljs-number">4</span>D<span class="hljs-number">39632</span>B<span class="hljs-number">6832595049466358776</span>B<span class="hljs-number">316475754</span>F<span class="hljs-number">4</span>B<span class="hljs-number">5848505</span>A<span class="hljs-number">33715878375156696</span>B<span class="hljs-number">75484</span>C<span class="hljs-number">342</span>B<span class="hljs-number">4439744633384</span>C<span class="hljs-number">377448486</span>E<span class="hljs-number">646473516</span>C<span class="hljs-number">4</span>C<span class="hljs-number">6</span>E<span class="hljs-number">6</span>D<span class="hljs-number">3449394</span>F<span class="hljs-number">792</span>B<span class="hljs-number">42563361693476457</span>A<span class="hljs-number">6</span>D<span class="hljs-number">707473344</span>C<span class="hljs-number">536546776</span>D<span class="hljs-number">66767166773</span>D<span class="hljs-number">3</span>D</pre></div><div id="981c"><pre><span class="hljs-symbol">Decrypted:</span> hello</pre></div><p id="26a3">In terms of the key pair we can view the key pair here:</p><div id="c0ef"><pre>Printing <span class="hljs-keyword">out</span> <span class="hljs-keyword">key</span>: { <span class="hljs-string">"primaryKeyId"</span>: 845905292, <span class="hljs-string">"key"</span>: [{ <span class="hljs-string">"keyData"</span>: { <span class="hljs-string">"typeUrl"</span>: <span class="hljs-string">"type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey"</span>, <span class="hljs-string">"keyMaterialType"</span>: <span class="hljs-string">"ASYMMETRIC_PUBLIC"</span>, <span class="hljs-string">"value"</span>: <span class="hljs-string">"EkQKBAgCEAMSOhI4CjB0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5jcnlwdG8udGluay5BZXNHY21LZXkSAhAQGAEYARogOyIb/MongoqTLNlQS9iRbqqhIrzE7w8w1SwpnVjsDpwiIQCrCIUxvLyqXUD9a3nDb3Cbs0YvNQB5wlGMxCLDFTmeDA=="</span> }, <span class="hljs-string">"outputPrefixType"</span>: <span class="hljs-string">"TINK"</span>, <span class="hljs-string">"keyId"</span>: 845905292, <span class="hljs-string">"status"</span>: <span class="hljs-string">"ENABLED"</span> }] }</pre></div><p id="2b17">The code is:</p><div id="3b91"><pre><span class="hljs-keyword">package</span> com.helloworld; <span class="hljs-keyword">import</span> java.util.Base64; <span class="hljs-keyword">import</span> com.google.crypto.tink.aead.AeadConfig; <span class="hljs-keyword">import</span> java.security.GeneralSecurityException; <span class="hljs-keyword">import</span> java.io.ByteArrayOutputStream;</pre></div><div id="8620"><pre>import com.google.crypto.tink.HybridDecrypt<span class="hljs-comment">;</span> import com.google.crypto.tink.HybridEncrypt<span class="hljs-comment">;</span> import com.google.crypto.tink.hybrid.HybridDecryptFactory<span class="hljs-comment">;</span> import com.google.crypto.tink.hybrid.HybridEncryptFactory<span class="hljs-comment">;</span> import com.google.crypto.tink.hybrid.HybridKeyTemplates<span class="hljs-comment">;</span> import com.google.crypto.tink.KeysetHandle<span class="hljs-comment">;</span></pre></div><div id="c9fb"><pre>import org.apache.commons.codec.binary.Hex<span class="hljs-comment">;</span> import com.google.crypto.tink.CleartextKeysetHandle<span class="hljs-comment">;</span> import com.google.crypto.tink.JsonKeysetWriter<span class="hljs-comment">;</span></pre></div><div id="4f8d"><pre><span class="hljs-keyword">import</span> com.google.crypto.tink.config.TinkConfig;</pre></div><div id="063b"><pre><span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">class</span> <span class="hljs-symbol">HelloWorld</span> {</pre></div><div id="7f11"><pre> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-type">static</span> <span class="hljs-type">void</span> <span class="hljs-title">main</span><span class="hljs-params">(<span class="hljs-type">String</span>[] args)</span> throws Exception </span>{ </pre></div><div id="a7bb"><pre> TinkConfig.register()<span class="hljs-comment">;</span></pre></div><div id="e9b7"><pre> <span class="hljs-keyword">try</span> {</pre></div><div id="62af"><pre> String plaintext<span class="hljs-operator">=</span><span class="hljs-string">"napier"</span><span class="hljs-comment">;</span> String aad<span class="hljs-operator">=</span><span class="hljs-string">"qwerty123"</span><span class="hljs-comment">;</span></pre></div><div id="fe4f"><pre> <span class="hljs-title class_">System</span>.<span class="hljs-property">out</span>.<span class="hljs-property">println</span>(<span class="hljs-string">"Text:<span class="hljs-char escape_">\t</span><span class="hljs-char escape_">\t</span>"</span><span class="hljs-operator">+</span><span class="hljs-variable">plaintext</span>); <span class="hljs-title class_">System</span>.<span class="hljs-property">out</span>.<span class="hljs-property">println</span>(<span class="hljs-string">"Password:<span class="hljs-char escape_">\t</span>"</span><span class="hljs-operator">+</span><span class="hljs-variable">aad</span>); </pre></div><div id="6c6e"><pre> KeysetHandle privateKeysetHandle <span class="hljs-operator">=</span> KeysetHandle.generateNew( HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM)<span class="hljs-comment">;</span> </pre></div><div id="cc30"><pre> Keys

Options

etHandle publicKeysetHandle <span class="hljs-operator">=</span> privateKeysetHandle.getPublicKeysetHandle()<span class="hljs-comment">;</span></pre></div><div id="c8b8"><pre> HybridEncrypt hybridEncrypt <span class="hljs-operator">=</span> HybridEncryptFactory.getPrimitive(publicKeysetHandle)<span class="hljs-comment">;</span></pre></div><div id="d5c6"><pre> <span class="hljs-built_in">byte</span>[] ciphertext = hybridEncrypt<span class="hljs-number">.</span>encrypt(plaintext<span class="hljs-number">.</span>getBytes(), <span class="hljs-keyword">aad</span><span class="hljs-number">.</span>getBytes())<span class="hljs-comment">;</span> </pre></div><div id="fe2a"><pre> byte[] encoded = Base64.getEncoder().encode(ciphertext); <span class="hljs-keyword">System</span>.<span class="hljs-keyword">out</span>.println("\nSig (Base64):\t"+ <span class="hljs-built_in">new</span> String(encoded)); <span class="hljs-keyword">System</span>.<span class="hljs-keyword">out</span>.println("Sig (Hex):"+ toHexString(encoded));</pre></div><div id="63cc"><pre> HybridDecrypt hybridDecrypt <span class="hljs-operator">=</span> HybridDecryptFactory.getPrimitive( privateKeysetHandle)<span class="hljs-comment">;</span> </pre></div><div id="10ef"><pre> <span class="hljs-built_in">byte</span>[] decrypted = hybridDecrypt<span class="hljs-number">.</span>decrypt(ciphertext, <span class="hljs-keyword">aad</span><span class="hljs-number">.</span>getBytes())<span class="hljs-comment">;</span> </pre></div><div id="595a"><pre> <span class="hljs-title class_">String</span> <span class="hljs-variable">s</span> <span class="hljs-operator">=</span> <span class="hljs-variable">new</span> <span class="hljs-title class_">String</span>(<span class="hljs-variable">decrypted</span>); <span class="hljs-title class_">System</span>.<span class="hljs-property">out</span>.<span class="hljs-property">println</span>(<span class="hljs-string">"<span class="hljs-char escape_">\n</span>Decrypted:<span class="hljs-char escape_">\t</span>"</span><span class="hljs-operator">+</span><span class="hljs-variable">s</span>); </pre></div><div id="02bf"><pre> <span class="hljs-keyword">System</span>.<span class="hljs-keyword">out</span>.println("\nPrinting out key:");</pre></div><div id="834a"><pre>
ByteArrayOutputStream outputStream <span class="hljs-operator">=</span> new ByteArrayOutputStream()<span class="hljs-comment">;</span></pre></div><div id="65f1"><pre> CleartextKeysetHandle.<span class="hljs-built_in">write</span>( publicKeysetHandle, JsonKeysetWriter.withOutputStream(outputStream));</pre></div><div id="5fc8"><pre> <span class="hljs-keyword">System</span>.<span class="hljs-keyword">out</span>.println(<span class="hljs-built_in">new</span> String(outputStream.toByteArray()));</pre></div><div id="e48b"><pre> <span class="hljs-keyword">System</span>.<span class="hljs-keyword">out</span>.println("\nPrinting out public key:");</pre></div><div id="705c"><pre> <span class="hljs-attr">outputStream</span> = new ByteArrayOutputStream()<span class="hljs-comment">;</span> </pre></div><div id="77ef"><pre> } catch (GeneralSecurityException e) { System.out.println(e); System.<span class="hljs-keyword">exit</span>(<span class="hljs-number">1</span>); }</pre></div><div id="27f1"><pre> }</pre></div><div id="ff5f"><pre> public static String toHexString( <span class="hljs-keyword">byte[] </span><span class="hljs-keyword">bytes </span>) { StringBuffer <span class="hljs-keyword">sb </span>= new StringBuffer( <span class="hljs-keyword">bytes.length*2 </span>); for( int i = <span class="hljs-number">0</span><span class="hljs-comment">; i < bytes.length; i++ )</span> { <span class="hljs-keyword">sb.append( </span>toHex(<span class="hljs-keyword">bytes[i] </span>>> <span class="hljs-number">4</span>) ); <span class="hljs-keyword">sb.append( </span>toHex(<span class="hljs-keyword">bytes[i]) </span>); }</pre></div><div id="2f27"><pre> <span class="hljs-function"><span class="hljs-keyword">return</span> sb.<span class="hljs-title">toString</span><span class="hljs-params">()</span></span>; } <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-function"><span class="hljs-keyword">char</span> <span class="hljs-title">toHex</span><span class="hljs-params">(<span class="hljs-keyword">int</span> nibble)</span> </span>{ <span class="hljs-keyword">final</span> <span class="hljs-keyword">char</span>[] hexDigit = { <span class="hljs-string">'0'</span>,<span class="hljs-string">'1'</span>,<span class="hljs-string">'2'</span>,<span class="hljs-string">'3'</span>,<span class="hljs-string">'4'</span>,<span class="hljs-string">'5'</span>,<span class="hljs-string">'6'</span>,<span class="hljs-string">'7'</span>,<span class="hljs-string">'8'</span>,<span class="hljs-string">'9'</span>,<span class="hljs-string">'A'</span>,<span class="hljs-string">'B'</span>,<span class="hljs-string">'C'</span>,<span class="hljs-string">'D'</span>,<span class="hljs-string">'E'</span>,<span class="hljs-string">'F'</span> }; <span class="hljs-keyword">return</span> hexDigit[nibble & <span class="hljs-number">0xF</span>]; }</pre></div><div id="8b8f"><pre>} </pre></div><p id="21d2">A demo of the method is <a href="https://asecuritysite.com/encryption/tink04">here</a>.</p><h2 id="d0ea">Conclusions</h2><p id="8e68">ECIES provides the ease of use of public key with the performance of symmetric key.</p></article></body>

The Ease of Public Key and Power of Symmetric Key: Meet Hybrid Encryption with Google Tink (ECIES)

Using public key and secret key

A demo of the method is here.

Google has released Tink and which is a multi-language, cross-platform cryptographic library. Hybrid Encryption is a combination of symmetric key encryption and public-key encryption. We encrypt with a newly created symmetric key, and then encrypt this with the public key of the recipient. The most popular public method is elliptic curve with Curve 25591, and the most popular symmetric method is AES.

Outline of method

With Elliptic curve integrated encryption scheme (ECIES), Alice generates a random private key (dA) and the takes a point on an elliptic curve (G) and then determines her public key (QA):

QA=dA×G

G and QA are thus points on an elliptic curve. Alice then sends QA to Bob. Next Bob will generate:

R=r×G

S=r×QA

and where r is a random number generated by Bob. The symmetric key (S) is then used to encrypt a message.

Alice will then receive the encrypted message along with R . She is then able to determine the same encryption key with:

S=dA×R

which is:

S=dA×(r×G)

S=r×(dA×G)

S=r×QA

and which is the same as the key that Bob generated.

The method is illustrated here:

Bob thus uses Alice’s public key to encrypt the newly created symmetric key.

Implementation with Google Tink

Google Tink is an open source repository for the integration of cryptography methods. It uses best practice in order to reduce risks, and also to simplify code integration. Currently it supports Java, C++ and Objective-C. As Java is well supported on Android devices, the code has already been integrated into a wide range of applications, including Google Pay.

We create the symmetric key set with:

KeysetHandle privateKeysetHandle = KeysetHandle.generateNew(
        HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM);

and the public key pair with:

KeysetHandle publicKeysetHandle =
        privateKeysetHandle.getPublicKeysetHandle();
    HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive(publicKeysetHandle);

The encryption and decryption are then (for a message of “plaintext” and a passphrase of “aad”:

byte[] ciphertext = hybridEncrypt.encrypt(plaintext.getBytes(), aad.getBytes());
    HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive(
        privateKeysetHandle);
    byte[] decrypted = hybridDecrypt.decrypt(ciphertext, aad.getBytes());

A sample run is:

Text:		hello
Password:	qwerty
Sig (Base64):	ATJrfYwE7x3tQ6d4Zu5vGZ8/2hW3433Dk1cfw8ca900YdH1vJM9c+h2YPIFcXwk1duuOKXHPZ3qXx7QVikuHL4+D9tF38L7tHHnddsQlLnm4I9Oy+BV3ai4vEzmpts4LSeFwmfvqfw==
Sig (Hex):41544A726659774537783374513664345A753576475A382F32685733343333446B3163667738636139303059644831764A4D39632B6832595049466358776B316475754F4B5848505A33715878375156696B75484C342B4439744633384C377448486E646473516C4C6E6D3449394F792B42563361693476457A6D707473344C536546776D66767166773D3D
Decrypted:	hello

In terms of the key pair we can view the key pair here:

Printing out key:
{
    "primaryKeyId": 845905292,
    "key": [{
        "keyData": {
            "typeUrl": "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey",
            "keyMaterialType": "ASYMMETRIC_PUBLIC",
            "value": "EkQKBAgCEAMSOhI4CjB0eXBlLmdvb2dsZWFwaXMuY29tL2dvb2dsZS5jcnlwdG8udGluay5BZXNHY21LZXkSAhAQGAEYARogOyIb/MongoqTLNlQS9iRbqqhIrzE7w8w1SwpnVjsDpwiIQCrCIUxvLyqXUD9a3nDb3Cbs0YvNQB5wlGMxCLDFTmeDA=="
        },
        "outputPrefixType": "TINK",
        "keyId": 845905292,
        "status": "ENABLED"
    }]
}

The code is:

package com.helloworld;
import java.util.Base64;
import com.google.crypto.tink.aead.AeadConfig;
import java.security.GeneralSecurityException;
import java.io.ByteArrayOutputStream;
import com.google.crypto.tink.HybridDecrypt;
import com.google.crypto.tink.HybridEncrypt;
import com.google.crypto.tink.hybrid.HybridDecryptFactory;
import com.google.crypto.tink.hybrid.HybridEncryptFactory;
import com.google.crypto.tink.hybrid.HybridKeyTemplates;
import com.google.crypto.tink.KeysetHandle;
import org.apache.commons.codec.binary.Hex;
import com.google.crypto.tink.CleartextKeysetHandle;
import com.google.crypto.tink.JsonKeysetWriter;
import com.google.crypto.tink.config.TinkConfig;
public final class HelloWorld {
  public static void main(String[] args) throws Exception {
    TinkConfig.register();
    try {
    String plaintext="napier";
    String aad="qwerty123";
    System.out.println("Text:\t\t"+plaintext);
    System.out.println("Password:\t"+aad);
    KeysetHandle privateKeysetHandle = KeysetHandle.generateNew(
        HybridKeyTemplates.ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM);
    KeysetHandle publicKeysetHandle =
        privateKeysetHandle.getPublicKeysetHandle();
    HybridEncrypt hybridEncrypt = HybridEncryptFactory.getPrimitive(publicKeysetHandle);
    byte[] ciphertext = hybridEncrypt.encrypt(plaintext.getBytes(), aad.getBytes());
    byte[] encoded = Base64.getEncoder().encode(ciphertext);
    System.out.println("\nSig (Base64):\t"+ new String(encoded));
    System.out.println("Sig (Hex):"+ toHexString(encoded));
    HybridDecrypt hybridDecrypt = HybridDecryptFactory.getPrimitive(
        privateKeysetHandle);
    byte[] decrypted = hybridDecrypt.decrypt(ciphertext, aad.getBytes());
    
    String s = new String(decrypted);
    System.out.println("\nDecrypted:\t"+s);
    System.out.println("\nPrinting out key:");
    
    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
    CleartextKeysetHandle.write( publicKeysetHandle, JsonKeysetWriter.withOutputStream(outputStream));
    System.out.println(new String(outputStream.toByteArray()));
    System.out.println("\nPrinting out public key:");
    outputStream = new ByteArrayOutputStream();
    } catch (GeneralSecurityException e) {
      System.out.println(e);
      System.exit(1);
    }
  }
  public static String toHexString( byte[] bytes )
  {
      StringBuffer sb = new StringBuffer( bytes.length*2 );
      for( int i = 0; i < bytes.length; i++ )
      {
          sb.append( toHex(bytes[i] >> 4) );
          sb.append( toHex(bytes[i]) );
      }
      return sb.toString();
  }
  private static char toHex(int nibble)
  {
      final char[] hexDigit =
      {
          '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
      };
      return hexDigit[nibble & 0xF];
  }
}

A demo of the method is here.

Conclusions

ECIES provides the ease of use of public key with the performance of symmetric key.

Security
Cryptography
Encryption
Cybersecurity
Recommended from ReadMedium