<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Varun Dwarkani</title>
    <description>The latest articles on DEV Community by Varun Dwarkani (@varundwarkani10).</description>
    <link>https://dev.to/varundwarkani10</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F209216%2Fd39404b0-2d61-464c-8b0e-9b5eabd1cea7.jpg</url>
      <title>DEV Community: Varun Dwarkani</title>
      <link>https://dev.to/varundwarkani10</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/varundwarkani10"/>
    <language>en</language>
    <item>
      <title>One News — Fast &amp; Latest News</title>
      <dc:creator>Varun Dwarkani</dc:creator>
      <pubDate>Thu, 19 Sep 2019 03:53:21 +0000</pubDate>
      <link>https://dev.to/varundwarkani10/one-news-fast-latest-news-4c77</link>
      <guid>https://dev.to/varundwarkani10/one-news-fast-latest-news-4c77</guid>
      <description>&lt;p&gt;In this busy world, we generally don’t find time for doing or reading things we love. We have our busy daily routine performing our tasks and getting exhausted by the end of the day. I had a similar story of mine but did come over it by using this amazing application.&lt;/p&gt;

&lt;p&gt;I always want to stay updated with the &lt;strong&gt;current affairs&lt;/strong&gt; and read &lt;strong&gt;all kinds of news&lt;/strong&gt; and happenings around the world but I am not able to do that and the reason is that I do not find the time. My busy schedule involving college, work, assignments, and others stop me from doing so. While I always wondered to read the news in a short and crisp manner, I did not find any source of doing so. The general news websites or applications are not so user-friendly and elaborate on the news a lot. I only get the news when I spend nearly 2–3 minutes reading the article which makes me irritated at times or bored with others.&lt;/p&gt;

&lt;p&gt;Recently, I came across an application which helps me read all the important news from around the world within 3 minutes. &lt;strong&gt;I used to spend 3 minutes reading every news and now in 3 minutes, I can read all the news saving up a lot of my time and staying updated like never before.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iasmc2HO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/axxhv50e7b8ktnlat6n3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iasmc2HO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/axxhv50e7b8ktnlat6n3.png" alt="App Display Images"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I do not have to worry about getting the news too late as the application provides the latest news always. While I am away in work but find time to read the messages through notifications, this application sends out important &lt;strong&gt;news notification with a beautiful image in just 15 words.&lt;/strong&gt; By spending just 10 seconds, I understand the important and recent news from around the world without even opening the application. The best part is that the application does not work as a clickbait asking the users to open the application every now and then to get the news. It provides all the news in the notification itself thus I am not forced to even unlock my device many times.&lt;/p&gt;

&lt;p&gt;The notification is not generalized. &lt;strong&gt;I get to choose what type of notifications I want to receive from various categories.&lt;/strong&gt; It provides news from various topics from around the world.&lt;/p&gt;

&lt;p&gt;While I can go on and on about this news application, the most important features which I liked in the very first impression was —&lt;/p&gt;

&lt;p&gt;a. &lt;strong&gt;A lightweight application&lt;/strong&gt; which is just 2 MB. All those Xiaomi users can now install the application without getting the Google Playstore warning on low storage.&lt;br&gt;
b. Simple and Sleek &lt;strong&gt;UI/UX&lt;/strong&gt;.&lt;br&gt;
c. &lt;strong&gt;Offline reading capability&lt;/strong&gt; — Now I can read the news without having to be online. It does not occupy more than 50 MB of my phone storage while other famous applications use up to 500 MB.&lt;br&gt;
d. &lt;strong&gt;Night Mode&lt;/strong&gt; to not strain my eyes at night.&lt;br&gt;
e. Read News from &lt;strong&gt;different languages and categories&lt;/strong&gt; — Technology, Sports, Entertainment, Politics and more.&lt;br&gt;
f. &lt;strong&gt;Hands-Free Mode&lt;/strong&gt; — The application allows the users to listen to the news without scrolling through.&lt;br&gt;
g. &lt;strong&gt;Bookmarks&lt;/strong&gt; — The important news can be saved to read later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--q9Edqa0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/emvxcx403ocxyuxnfmvu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--q9Edqa0N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/emvxcx403ocxyuxnfmvu.png" alt="App Display Images"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;h. &lt;strong&gt;Share&lt;/strong&gt; — The application allows the users to share the news they find which are interesting with their friends &amp;amp; family on various platforms.&lt;br&gt;
i. Read the &lt;strong&gt;entire news from the official source&lt;/strong&gt; to get more insights on the news.&lt;br&gt;
j. &lt;strong&gt;Read news from various Newspapers&lt;/strong&gt; ranging in 14 languages and 4 categories consisting of 1000+ Newspapers with multiple controls — Zoom, Load faster, Add as favorites, Share the article and add their own newspaper.&lt;br&gt;
k. &lt;strong&gt;Videos&lt;/strong&gt; — The application also has a video section which adds useful and funny videos from different language and categories.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kJ8XNHNU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/39cdrmbqcclkpltyz8o1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kJ8XNHNU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/39cdrmbqcclkpltyz8o1.png" alt="App Features"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s not it. The cherry on the topic is their &lt;strong&gt;premium notification&lt;/strong&gt; which appeals the eyes when looked through the notification panel and understand the news very easily.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cOd5f3Rj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/og87f22xh2285vr6w4xj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cOd5f3Rj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/og87f22xh2285vr6w4xj.jpeg" alt="App Notifications"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Introducing &lt;strong&gt;One News&lt;/strong&gt; — The All In One Sleek and Simple News App.&lt;br&gt;
Android users can download the application from — &lt;a href="http://bit.ly/2YPqmeF"&gt;http://bit.ly/2YPqmeF&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The iOS and Desktop users need not be disappointed as we also have a web app for the same — &lt;a href="https://onenews.dwarsoft.com/"&gt;https://onenews.dwarsoft.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you like the application, give us a heads up on &lt;strong&gt;Product Hunt&lt;/strong&gt; - &lt;a href="https://www.producthunt.com/posts/one-news-fast-latest-news"&gt;https://www.producthunt.com/posts/one-news-fast-latest-news&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt; — I am the Co-Founder &amp;amp; CTO of the company &lt;strong&gt;Dwarsoft Solutions&lt;/strong&gt; which developed the application — &lt;strong&gt;One News&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>news</category>
      <category>android</category>
      <category>playstore</category>
    </item>
    <item>
      <title>Securing secret key in Android using Keystore</title>
      <dc:creator>Varun Dwarkani</dc:creator>
      <pubDate>Thu, 08 Aug 2019 18:26:59 +0000</pubDate>
      <link>https://dev.to/varundwarkani10/securing-secret-key-in-android-using-keystore-1kj6</link>
      <guid>https://dev.to/varundwarkani10/securing-secret-key-in-android-using-keystore-1kj6</guid>
      <description>&lt;p&gt;At some point in time, we all wanted to keep our data secure from being hacked/reverse engineered. The basic security mechanisms like,&lt;/p&gt;

&lt;p&gt;a. ProGuard, ShrinkResources &amp;amp; minifyEnabled&lt;br&gt;
b. Hiding in Manifest&lt;br&gt;
c. Hiding in Build.Gradle&lt;br&gt;
d. Storing in MySQL DB/Room DB/SharedPreference&lt;br&gt;
e. Hiding in Strings.xml.&lt;/p&gt;

&lt;p&gt;All these methods fail to provide maximum security. The most common and known logic of securing the key can be bypassed either by reversing and taking it from dex-&amp;gt;jar file or by rooting the device and accessing the device storage.&lt;br&gt;
But, there is one more method that beats them all. The mechanism which is generally used by applications for storing very sensitive data like Credit Card details, Bank Account and such.&lt;/p&gt;

&lt;p&gt;Keystore is bound to hardware security which is generally used to store cryptographic keys. It becomes incredibly difficult for hackers to get access to it since a Keystore is very specific to every application. More of introduction done let us jump to the code now -&lt;/p&gt;

&lt;p&gt;Declare few variables in &lt;strong&gt;Cryptor.java&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;private static final String &lt;strong&gt;TRANSFORMATION&lt;/strong&gt; = “AES/GCM/NoPadding”;&lt;br&gt;
private static final String &lt;strong&gt;ANDROID_KEY_STORE&lt;/strong&gt; = “AndroidKeyStore”;&lt;br&gt;
private byte[] &lt;strong&gt;iv&lt;/strong&gt;;&lt;br&gt;
private KeyStore &lt;strong&gt;keyStore&lt;/strong&gt;;&lt;br&gt;
private static final String &lt;strong&gt;SAMPLE_ALIAS&lt;/strong&gt; = “MYALIAS”;&lt;/p&gt;

&lt;p&gt;a. TRANSFORMATION is used for setting the algorithm which will be used for encoding.&lt;br&gt;
b. iv is known as Initialization Vector which is an arbitrary number used along with a secret key for encryption. (It can be stored in public storage like SharedPreference, Room DB or MySQL DB).&lt;br&gt;
c. SAMPLE_ALIAS is used to access the entity stored inside the Keystore.&lt;/p&gt;
&lt;h1&gt;
  
  
  ENCRYPTING DATA
&lt;/h1&gt;

&lt;p&gt;For encrypting a value with the Keystore, we can do it by,&lt;/p&gt;

&lt;p&gt;a. Create an object of the Cryptor class.&lt;br&gt;
b. Use a setIv method to init the cipher using a secret key in Cryptor class.&lt;br&gt;
c. Encrypt the text using an encryption function defined in Cryptor class.&lt;br&gt;
d. Store the Iv and encrypted text (The Iv can be made public and it does not cause any issue) in SharedPreference or Room Database.&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;RegistrationActivity.java&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Cryptor cryptor = new Cryptor();
try {
    cryptor.setIv();
    prefs.edit().putString("encryptedKey", cryptor.encryptText("text_to_be_encrypted")).apply();
    prefs.edit().putString("keyIv", cryptor.getIv_string()).apply();
    Intent intent = new Intent(RegistrationActivity.this, HomeScreen.class);
    startActivity(intent);
    finish();
} catch (NoSuchPaddingException e) {
    unexpectedError();
    e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
    unexpectedError();
    e.printStackTrace();
} catch (NoSuchProviderException e) {
    unexpectedError();
    e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
    unexpectedError();
    e.printStackTrace();
} catch (InvalidKeyException e) {
    unexpectedError();
    e.printStackTrace();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In Cryptor.java, we define the following functions&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. setIv() method :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void setIv() throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException {
    Cipher cipher = Cipher.getInstance(TRANSFORMATION);
    cipher.init(Cipher.ENCRYPT_MODE, getSecretKey_en());
    iv = cipher.getIV();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. getSecretKey_en() method :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@NonNull
private SecretKey getSecretKey_en() throws NoSuchAlgorithmException,
        NoSuchProviderException, InvalidAlgorithmParameterException {
    final KeyGenerator keyGenerator;
    if (android.os.Build.VERSION.SDK_INT &amp;gt;= android.os.Build.VERSION_CODES.M) {
        keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
        keyGenerator.init(new KeyGenParameterSpec.Builder(Cryptor.SAMPLE_ALIAS,
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .build());
        return keyGenerator.generateKey();
    } else {
        keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
        keyGenerator.init(new KeyGenParameterSpec.Builder(Cryptor.SAMPLE_ALIAS,
                KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                .build());
        return keyGenerator.generateKey();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. encryptText(String string_to_encrypt) :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public String encryptText(String string_to_encrypt) {
    try {
        final byte[] encryptedText = encryptData(string_to_encrypt);
        return Base64.encodeToString(encryptedText, Base64.DEFAULT);
    } catch (NoSuchAlgorithmException | NoSuchProviderException |
            NoSuchPaddingException | InvalidKeyException e) {
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException |
            IllegalBlockSizeException | BadPaddingException e) {
        e.printStackTrace();
    }
    return "";
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. encryptData(String text_to_encrypt) :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private byte[] encryptData(final String textToEncrypt)
        throws NoSuchAlgorithmException,
        NoSuchProviderException, NoSuchPaddingException, InvalidKeyException,
        InvalidAlgorithmParameterException, BadPaddingException,
        IllegalBlockSizeException {
    final Cipher cipher = Cipher.getInstance(TRANSFORMATION);
    cipher.init(Cipher.ENCRYPT_MODE, getSecretKey_en());
    iv = cipher.getIV();
    return (cipher.doFinal(textToEncrypt.getBytes(StandardCharsets.UTF_8)));
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. getIv_string() :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public String getIv_string() {
    return Base64.encodeToString(iv, Base64.DEFAULT);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; We generate a secret key using the keyStore with specific algorithms and the ALIAS. the secret key which is generated is used to init the cipher and get the IV. The encrypt text function uses the text and the iv to encrypt the text in the Keystore and gives the encrypted text which can be stored in any general storage medium.&lt;/p&gt;

&lt;h1&gt;
  
  
  DECRYPTING DATA
&lt;/h1&gt;

&lt;p&gt;For decrypting a value with the Keystore, we can do it by,&lt;br&gt;
a. Create an object of the Cryptor class.&lt;br&gt;
b. Initialize the KeyStore instance.&lt;br&gt;
c. Use the decrypt function by passing the encrypted text and the iv (stored in SharedPreference or Room Database).&lt;/p&gt;

&lt;p&gt;In &lt;strong&gt;HomeScreen.java&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;String iv = prefs.getString("keyIv", "null");
String encrypted = prefs.getString("encryptedKey", "");
try {
    Cryptor cryptor = new Cryptor();
    cryptor.initKeyStore();
    String decrypted = cryptor.decryptText(encrypted, iv);
} catch (KeyStoreException e) {
    e.printStackTrace();
} catch (CertificateException e) {
    e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In &lt;strong&gt;Cryptor.java&lt;/strong&gt;, add the following functions&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.initKeyStore() :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void initKeyStore() throws KeyStoreException, CertificateException,
        NoSuchAlgorithmException, IOException {
    keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
    keyStore.load(null);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. decryptText(String encrypted_string, String iv) :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public String decryptText(String encrypted, String iv) {
    try {
        return decryptData(encrypted, Base64.decode(iv,Base64.DEFAULT));
    } catch (UnrecoverableEntryException | NoSuchAlgorithmException |
            KeyStoreException | NoSuchPaddingException | InvalidKeyException e) {
        e.printStackTrace();
    } catch (IllegalBlockSizeException | BadPaddingException | InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
    return "";
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. decryptData(String encrypted_string, byte[] Iv) :&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private String decryptData(String encrypted, final byte[] encryptionIv)
        throws UnrecoverableEntryException, NoSuchAlgorithmException, KeyStoreException,
        NoSuchPaddingException, InvalidKeyException,
        BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException {
    final Cipher cipher = Cipher.getInstance(TRANSFORMATION);
    final GCMParameterSpec spec = new GCMParameterSpec(128, encryptionIv);
    cipher.init(Cipher.DECRYPT_MODE, getSecretKey_de(), spec);
    byte[] encryptedData = Base64.decode(encrypted,Base64.DEFAULT);
    return new String(cipher.doFinal(encryptedData), StandardCharsets.UTF_8);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt; While decrypting, we get the stored Iv and encrypted text stored in our one of the storage medium. We initialize the Keystore using the ANDROID_KEY_STORE and decrypt the text using the Iv and by the init and doFinal method of the Cipher.&lt;/p&gt;

&lt;h1&gt;
  
  
  CONCLUSION:
&lt;/h1&gt;

&lt;p&gt;So, with the above implementation, secrets are now safe in the KeyStore. Why it is probably the best method is because KeyStore is very specific to the application. It cannot be retrieved and hence the text cannot be decrypted without it. Many applications which stores the Credit Card and other sensitive data of the users use this encryption method to keep it safe.&lt;br&gt;
For the entire code, you can look into my GitHub repository.&lt;br&gt;
Explaining the code, I have defined files like — Cryptor.java, RegistrationActivity.java and HomeScreen.java. I have also used Room Database (launched by Google in I/O 2018) which provides high-level security than SQLLite (can be accessed if the device is rooted) to store the username and password to authenticate the registered users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/varundwarkani/KeystoreEncryption-Android"&gt;https://github.com/varundwarkani/KeystoreEncryption-Android&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>security</category>
      <category>cryptography</category>
      <category>java</category>
    </item>
  </channel>
</rss>
