{"id":14,"date":"2019-01-19T18:16:00","date_gmt":"2019-01-19T18:16:00","guid":{"rendered":"\/colin\/morethanfour\/post\/AES-Encryption-between-Informatica-and-PostgreSQL"},"modified":"2019-01-19T18:16:00","modified_gmt":"2019-01-19T18:16:00","slug":"aes-encryption-between-informatica-and-postgresql","status":"publish","type":"post","link":"https:\/\/spacefold.com\/colin\/morethanfour\/2019\/01\/19\/aes-encryption-between-informatica-and-postgresql\/","title":{"rendered":"AES Encryption between Informatica and PostgreSQL"},"content":{"rendered":"<p>We encountered a situation where encrypted data exported from Informatica could not be decrypted by PostgreSQL, once we&#8217;d loaded it into a table.<\/p>\n<p>If you found this page looking for a solution, save your time. I don&#8217;t have a solution, I just wanted to make some notes.<\/p>\n<p><strong>How does Informatica encrypt data?<\/strong><\/p>\n<p>According to this <a href=\"https:\/\/kb.informatica.com\/howto\/6\/Pages\/17\/319482.aspx\" target=\"_blank\" rel=\"noopener noreferrer\">knowledgebase article<\/a>:<\/p>\n<p><em>AES_DECRYPT needs binary data as input. Hence when we first encrypt the data using the AES_ENCRYPT function, the data transformed by this function has to be encoded in base64 format. This transformed data can then be used as an input to the AES_DECRYPT function.<\/em><\/p>\n<p>In other words:<\/p>\n<p>   CIPHERTEXT = Base64_Encode( AES_Encrypt( PLAINTTEXT ))<\/p>\n<p>and <\/p>\n<p>   PLAINTEXT = AES_Decrypt( Base64_Decode( CIPHERTEXT ))<\/p>\n<p>According to <a href=\"https:\/\/network.informatica.com\/thread\/4227\" target=\"_blank\" rel=\"noopener noreferrer\">this thread<\/a>:<\/p>\n<p><em>[informatica&#8217;s] AES_ENCRYPT function uses the combination as follows which is expressed in terms of functions in DBMS_CRYPTO package of Oracle:   DBMS_CRYPTO.ENCRYPT_AES128 + DBMS_CRYPTO.CHAIN_CBC + DBMS_CRYPTO.PAD_ZERO<\/em><\/p>\n<p>From Oracle&#8217;s documentation, we get:<\/p>\n<blockquote>\n<p>DBMS_CRYPTO.ENCRYPT_AES128   Advanced Encryption Standard. Block cipher. Uses 128-bit key size.<br \/>DBMS_CRYPTO.CHAIN_CBC              Cipher Block Chaining. Plaintext is XORed with the previous ciphertext block before it is encrypted.<br \/>DBMS_CRYPTO.PAD_ZERO                Provides padding consisting of zeroes<\/p>\n<\/blockquote>\n<p>So far, so good.<\/p>\n<p><strong>Ensure the pgcrypto extension is installed in PostgreSQL:<\/strong><\/p>\n<p>In psql:<\/p>\n<div id=\"codeSnippetWrapper\">\n<pre id=\"codeSnippet\" style=\"border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4\">=&gt; \\dx<br> hstore  | 1.4     | public     | data type <span style=\"color: #0000ff\">for<\/span> storing sets of (key, value) pairs<br> plpgsql | 1.0     | pg_catalog | PL\/pgSQL procedural language<br> <br>=&gt; create extension <span style=\"color: #0000ff\">if<\/span> not exists pgcrypto;<br>CREATE EXTENSION<br> <br>=&gt; \\dx<br> hstore   | 1.4     | public     | data type <span style=\"color: #0000ff\">for<\/span> storing sets of (key, value) pairs<br> pgcrypto | 1.3     | public     | cryptographic functions<br> plpgsql  | 1.0     | pg_catalog | PL\/pgSQL procedural language<\/pre>\n<p><\/div>\n<p>Looking at the docs for the raw base functions in pgcrypto, it suggests that the default settings for encrypt\/descrypt will use MODE=CBC and PADDING=PKCS (any length) which suggests zero padding but that&#8217;s a guess. So I think it should match Informatica, at least according to the docs.<br \/>See <a href=\"https:\/\/www.postgresql.org\/docs\/9.5\/pgcrypto.html\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/www.postgresql.org\/docs\/9.5\/pgcrypto.html<\/a><\/p>\n<p>And yet, using the following test code yields an error:<\/p>\n<div id=\"codeSnippetWrapper\">\n<pre id=\"codeSnippet\" style=\"border-top-style: none; font-size: 8pt; overflow: visible; border-left-style: none; font-family: 'Courier New', courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4\"><p>=&gt; <span style=\"color: #0000ff\">select<\/span> pgp_sym_decrypt( decode(<span style=\"color: #006080\">'BI830ZHd2kimJTfMD8E07mSTa8HDUbU\/lbKFUDl73FrqI6uwAH7oCwPRGjxUkUZw'<\/span>,<span style=\"color: #006080\">'base64'<\/span>), <br>                           <span style=\"color: #006080\">'Abc123Abc123Abc123'<\/span>, <br>                           <span style=\"color: #006080\">'cipher-algo=aes128'<\/span> );<br><br><font color=\"#ff0000\">ERROR:  Wrong key or corrupt data<\/font><\/p><\/pre>\n<p><\/div>\n<p>In this example, I&#8217;ve replaced the key text with a random string value &#8211; we didn&#8217;t actually use that value.<\/p>\n<p>I am pretty confident that the encryption key is correct; less confident that the cipher text is not corrupt, but in simple tests where I DO have confidence, we still get the same error. Where does this leave us? With data we can&#8217;t decrypt, unless we can figure out the difference.<\/p>\n<p>Of course, we can encrypt and decrypt values successfully if we stay in the DB domain and use only the PostgreSQL pgcrypto API to perform the encryption. It&#8217;s only data coming from Informatica that is giving us trouble.<\/p>\n<p>Assuming the process that is extracting data from Informatica is not corrupting the data, it has to be some difference between the two encryption algorithms.<\/p>\n<p>I&#8217;ll continue to research this and if we find a solution, update this post, of course.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We encountered a situation where encrypted data exported from Informatica could not be decrypted by PostgreSQL, once we&#8217;d loaded it into a table. If you found this page looking for a solution, save your time. I don&#8217;t have a solution, I just wanted to make some notes. How does Informatica encrypt data? According to this [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[],"class_list":["post-14","post","type-post","status-publish","format-standard","hentry","category-postgresql","post-preview"],"_links":{"self":[{"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/posts\/14","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/comments?post=14"}],"version-history":[{"count":0,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/posts\/14\/revisions"}],"wp:attachment":[{"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/media?parent=14"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/categories?post=14"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/spacefold.com\/colin\/morethanfour\/wp-json\/wp\/v2\/tags?post=14"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}