Sunday, February 28, 2021
  • Setup menu at Appearance » Menus and assign menu to Top Bar Navigation
Advertisement
  • AI Development
    • Artificial Intelligence
    • Machine Learning
    • Neural Networks
    • Learn to Code
  • Data
    • Blockchain
    • Big Data
    • Data Science
  • IT Security
    • Internet Privacy
    • Internet Security
  • Marketing
    • Digital Marketing
    • Marketing Technology
  • Technology Companies
  • Crypto News
No Result
View All Result
NikolaNews
  • AI Development
    • Artificial Intelligence
    • Machine Learning
    • Neural Networks
    • Learn to Code
  • Data
    • Blockchain
    • Big Data
    • Data Science
  • IT Security
    • Internet Privacy
    • Internet Security
  • Marketing
    • Digital Marketing
    • Marketing Technology
  • Technology Companies
  • Crypto News
No Result
View All Result
NikolaNews
No Result
View All Result
Home Technology Companies

A cryptographic approach to protecting passwords in the cloud

January 14, 2019
in Technology Companies
Configure multifactor authentication for IBM Cloud Node.js applications
587
SHARES
3.3k
VIEWS
Share on FacebookShare on Twitter

Credit: IBM

Keep password data safe even after a breach

You might also like

2021 is the year that open source overcomes its diversity problems – IBM Developer

The Case of the Miscoded Credentials – IBM Developer

Two new Call for Code for Racial Justice projects just went open source – IBM Developer


In this article, back-end developers learn why it is important to use
encryption and how to use it effectively to protect user information on
the cloud, especially passwords, so that even a data leak can’t be cracked
in less than decades. Security is an ever important topic in the cloud
that is crucial to full-stack development and is essential on all products
and services.

Let’s begin by addressing these straightforward things to do (or not to do)
when you are considering security in development:

  • Always choose to use someone else’s hashing/encryption library that
    others have already scrutinized and reviewed.
  • Don’t print passwords to logs!
  • Use some form of key management service.
  • Don’t commit secrets (API keys, passwords) in the code
    repository.

In this article, I’m going to walk you through an example app to focus on
ways in which to encrypt critical data. For the storage of passwords that
are covered in this article, we will be using a SQLite
database
, since it is readily available on almost any system. The
same principles and ideas are in use almost everywhere, and the database
system should not really matter (although depending on the chosen
database, there can be better ways to hash and secure user information). I
also want to show what happens if you were to lose the database file, but
still keep user hash intact and
uncrackable.

Using bcrypt

bcrypt is one of the
most widely used functions available today for password hashing. It is
available for most programming languages and often there are
super-specific modules that are available for specific frameworks and
databases. Let’s look at this repo example.
This code is commonly used with Node.js and is incredibly straightforward
(it allows the salting and hashing functions to be called either
sync or async). It also allows you to not worry
about the implementation details or how salting is done, and instead
allows you to focus on preventing accidental password leaks.

What is hashing, salting, and
encryption?

While hashing and encryption might not seem different and can be used
interchangeably, they are actually quite different and have different use
cases. A hash function takes some input and has one-way mapping to an
output. While there is a spectrum of hashing techniques and algorithms, I
recommend bcrypt for passwords. You can read more about cryptographic hash functions here, but it is generally not
necessary to understand the underlying details for these functions.
Salting is used during hashing, and acts as additional
information that is supplied to the hash functions so that if one hash is
found out (either by accident or brute force), you are unable to check
other hashes that might have a similar input. For example,
user_1 has a password that is identical to
user_2‘s password. These users would not have had their
passwords found out if salting was used in the hash function. To read more
about this function, there are a variety of information
and examples here
.

Alternatively, encryption is a one-to-one mapping of some input to an
output. An important key difference is that it is reversible if you have
the encryption key.

You can use hashing to check an input to another input later, but
you don’t want to store the input outright (passwords, pin numbers, and
more). Encryption can be used when you are sending messages (and both
parties have a key to encode/decode), or if you want to store some private
information (such as home address or credit card), but need a way to
retrieve this information later.

The front end

Because the focus of this article is not on the front end, we are not
going to get into using anything that would add complications or another
framework to worry about. Instead, we are going to use two forms for
login/register on the same page. We won’t do anything with these forms
besides using super simple bootstrapping, since that isn’t the focus in
this article.

  <form action="/signin" method="post">
  

      <div class="row">
        <div class="col">
         
          <input name="email" type="email" class="form-control" placeholder="email"/>
        </div>
        <div class="col">


          <input name="password" type="password" class="form-control" placeholder="password"/>
        </div>
        <div class="col">
          <button class="btn btn-dark">sign in</button>
        </div>
     

  </form>
  

  <form action="/register" method="post">
 
      <div class="row">
        <div class="col">
         
          <input name="email" type="email" class="form-control" placeholder="email"/>
        </div>
        <div class="col">
          
          <input name="password" type="password" class="form-control" placeholder="password"/>
        </div>
        <div class="col">
          <button class="btn btn-dark">register</button>
        </div>
      </div>
   
  </form>

We are also posting the inputs to the back end from the form and not
dealing with checking/creating/setting sessions, since that doesn’t follow
the scope of this article either, and can be quite expansive, depending
on what the goal or aim of your application is.

Creating the back end

Next, we are going to run the back end in Node.js by using the Express
framework and SQLite to make the most basic system possible for the
purposes of this article.

const path = require('path')
const bcrypt = require('bcrypt')
const bodyParser = require('body-parser')
const sqlite = require('sqlite')

const express = require('express')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))

const dbPromise = sqlite.open('./database.sqlite', { Promise })
const saltRounds = 10

All that we are doing here is creating a promise for the database, generating a
salt, and creating the application and simple middleware to get the
username/password, along with loading some libraries that we want to
use.

Routes

In terms of what our server will do, we will have a route to log in and a
route for the user to register. They are separated to understand what is
happening in the system, yet are not doing anything (well, anything
that is related to sessions/cookies/etc.). Once the passwords match, we (rather
simply) show how hashing a password would be done and then be checked. The
login route is almost identical to the register route, and we are not
doing any data validation on either route, although we are checking for an
email on the HTML form.

app.get('/', async (req,res) => {
 res.sendFile(path.join(__dirname, '/main.html'))
})

app.post('/register', async (req, res) => {
  const db = await dbPromise

  // check if user already exists
  const checkUser = await db.get('SELECT * FROM Users WHERE email = ?', req.body.email)
  if (checkUser) {
    return res.send('user already exists')
  }

  const hashedPassword = await bcrypt.hash(req.body.password, saltRounds)
  const resp = await db.run(`INSERT INTO Users VALUES(?,?)`, req.body.email, hashedPassword)
  res.send('registered')
})

The register route checks whether a user exists in the database and whether
or not we inserted them into the database with a hashed password. Keep in
mind that we are not doing anything to mitigate SQL injections or various
other forms of hacking/abuse. If the user does not exist, we hash the
password with the bcrypt hash function and it salts it for us, since we
provided the number of rounds to salt. This hashing allows us to store the
user’s password in such a way that we can check the password in the future
if he/she types it in. We are not personally capable of looking up the
password. Also, we should not be printing the password to the user’s logs,
and we would likely want to create the ability to check a password and save a user’s password into a hash by using a database
model
.

While the login route is almost identical (and we could easily refactor
this to make it more DRY, but we are going for understanding here), there is a slightly
different line with:

const passwordMatch = await bcrypt.compare(req.body.password, user.password)

All this does is to use Bcrypt to compare the hashed password and the
password that the user typed in on the front end for us and returns true or
false. Since the salt is incorporated into the hash, we do not need to
explicitly use it to compare. Below is the complete server.js to run:

While the login route is almost identical (and we could easily refactor
this to make it more DRY, but we are going for understanding here), there
is a slightly different line with:

const passwordMatch = await bcrypt.compare(req.body.password, user.password)

All the above line does is to use Bcrypt to compare the hashed password and
the password that the user typed on the front end for us and returns as
true or false. Since the salt is incorporated into the hash, we do not
need to explicitly use it to compare. The below code listing is the
complete server.js to
run:

const bcrypt = require('bcrypt')
const bodyParser = require('body-parser')


const express = require('express')
const app = express()

app.post('/register', async (req, res) => {
  const db = await dbPromise



  const hashedPassword = await bcrypt.hash(req.body.password, saltRounds)
  const resp = await db.run(`INSERT INTO Users VALUES(?,?)`, req.body.email, hashedPassword)
  res.send('registered')
})


app.post('/signin', async (req, res) => {
  const db = await dbPromise
  const user = await db.get('SELECT * FROM Users WHERE email = ?', req.body.email)

  if (!user) {
    return res.send('user doesnt exist')
  }


  const passwordMatch = await bcrypt.compare(req.body.password, user.password)
  if (passwordMatch) {

    return res.send('signed in')
  }
  res.send('password does not match')
})


app.listen(PORT, async () => {

  console.log(`app listening at http://localhost:${PORT}`)
})

Now install the dependencies:

yarn add bcrypt express body-parser sqlite.

Run the server Node server.js, and open http://localhost:8080.
Then try both signing in and creating a user, and sign in again.

Sending unencrypted passwords over the
net!

Although this article is just to show you how to store and hash passwords,
and you are not keeping the plaintext password of users, we are still
sending the plaintext between the browser and the back end since we are
not using HTTPS. If this example was in production, hackers can easily see
these passwords (both the sign in and register) sent between the server
and the client if they were in the middle of this communication. There are
tons of different ways to actually deal with preventing man-in-the-middle hacks, but for the sake of
simplicity we are going to deal with it in Express and generate
self-signed SSL certificates as an example for how this would work. Keep
in mind that these are not signed in the same way as getting certificates
from LetsEncrypt or various other providers of SSL/TLS certs.

First, we need to install OpenSSL either via a package manager or from their official website. On
macOS, if you have homebrew already installed, you
can simply write:

brew-install Openssl

Next, you will want to run the command to generate a key and a
certificate:

openSSL req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem
-days 30

This command will require you to enter some information, but in the end you
will have a key.pem and a cert.pem. With these,
you can add the following to the top of server.js (note that
we are using the https standard library from Node.js now):

const fs = require('fs')
const https = require('https')

const options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem')
}

At the bottom of our code, we previously had:

const PORT = 8080
app.listen(PORT, async () => {
  const db = await dbPromise
  await db.run("CREATE TABLE IF NOT EXISTS Users (email TEXT, password TEXT)")
  console.log(`app listening at http://localhost:${PORT}`)
})

We will change the previous code above to:

const PORT = 8081
https.createServer(options, app)
  .listen(PORT, async () => {
    const db = await dbPromise
    await db.run("CREATE TABLE IF NOT EXISTS Users (email TEXT, password TEXT)")
    console.log(`app listening at https://localhost:${PORT}`)
  })

At this point, we would be only using HTTPS and would be sending the
password encrypted to our server, and the passwords would be hashed when
saving to our database.

Worst case scenario: The database gets leaked

Let’s imagine that our server was hacked, or some
other exploit occurred, and our SQLite (or any database) got
leaked. While this scenario is terrible, we can at least be confident that
the user passwords themselves should be safe from being used and
we minimize the chances of requesting users to change their passwords elsewhere.
For instance, Figure 1 below shows that instead of seeing a password
secret for user graham@test.xyz, the hash is
useless to hackers who try to use it.

fig01.png

Conclusion: Other alternatives for cloud security

While the instance of creating and storing user data might be the most
straightforward route, there are alternatives that allow you to maintain
information about who a user is (via something like OAuth that allows a
user to sign in on a peripheral service and you get back authentication
information, or signing in through an email). Alternative routes mean that
you don’t have to store secret information about users that can be a
potential liability. While there might be many ways to obfuscate and
protect a user’s information that you are storing in some database, there
is almost always guidance in whatever server frameworks documentation and
database you are using for security best practices.

For instance, visit Express.js’s Best Practices as it lists numerous topics lthat
were not covered in this article. One example that was not covered here was using
Helmet
to prevent some well-known HTTP headers vulnerabilities
. There are
also recommendations for things such as SQL injection mitigation and
rate-limiting to prevent brute force guessing. While there is no single
and simple way to mitigate all these issues, it never is extremely
difficult to look over the docs or suggestions online.


Downloadable resources

Related topics

Credit: IBM

Previous Post

QUT predicts erratic flight paths with multiple machine learning techniques - Software

Next Post

Good news for job-seekers! 1,286 openings in Amazon India, the highest in Asia-Pacific

Related Posts

Introducing the technology preview of IBM API Hub on IBM Developer, where you can discover, try, adopt, and consume APIs from IBM and our ecosystem partners – IBM Developer
Technology Companies

2021 is the year that open source overcomes its diversity problems – IBM Developer

February 27, 2021
Introducing the technology preview of IBM API Hub on IBM Developer, where you can discover, try, adopt, and consume APIs from IBM and our ecosystem partners – IBM Developer
Technology Companies

The Case of the Miscoded Credentials – IBM Developer

February 24, 2021
Six courses to build your technology skills in 2021 – IBM Developer
Technology Companies

Two new Call for Code for Racial Justice projects just went open source – IBM Developer

February 20, 2021
Introducing the technology preview of IBM API Hub on IBM Developer, where you can discover, try, adopt, and consume APIs from IBM and our ecosystem partners – IBM Developer
Technology Companies

Introducing the technology preview of IBM API Hub on IBM Developer, where you can discover, try, adopt, and consume APIs from IBM and our ecosystem partners – IBM Developer

February 18, 2021
Six courses to build your technology skills in 2021 – IBM Developer
Technology Companies

Project OWL announces new release of ClusterDuck Protocol to build emergency mesh networks – IBM Developer

February 17, 2021
Next Post
Good news for job-seekers! 1,286 openings in Amazon India, the highest in Asia-Pacific

Good news for job-seekers! 1,286 openings in Amazon India, the highest in Asia-Pacific

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recommended

Plasticity in Deep Learning: Dynamic Adaptations for AI Self-Driving Cars

Plasticity in Deep Learning: Dynamic Adaptations for AI Self-Driving Cars

January 6, 2019
Microsoft, Google Use Artificial Intelligence to Fight Hackers

Microsoft, Google Use Artificial Intelligence to Fight Hackers

January 6, 2019

Categories

  • Artificial Intelligence
  • Big Data
  • Blockchain
  • Crypto News
  • Data Science
  • Digital Marketing
  • Internet Privacy
  • Internet Security
  • Learn to Code
  • Machine Learning
  • Marketing Technology
  • Neural Networks
  • Technology Companies

Don't miss it

Cybercrime groups are selling their hacking skills. Some countries are buying
Internet Security

Cybercrime groups are selling their hacking skills. Some countries are buying

February 28, 2021
New AI Machine Learning Reduces Mental Health Misdiagnosis
Machine Learning

Machine Learning May Reduce Mental Health Misdiagnosis

February 28, 2021
Why would you ever trust Amazon’s Alexa after this?
Internet Security

Why would you ever trust Amazon’s Alexa after this?

February 28, 2021
AI & ML Are Not Same. Here's Why – Analytics India Magazine
Machine Learning

AI & ML Are Not Same. Here's Why – Analytics India Magazine

February 27, 2021
Microsoft: We’ve open-sourced this tool we used to hunt for code by SolarWinds hackers
Internet Security

Microsoft: We’ve open-sourced this tool we used to hunt for code by SolarWinds hackers

February 27, 2021
Is Wattpad and its machine learning tool the future of TV? — Quartz
Machine Learning

Is Wattpad and its machine learning tool the future of TV? — Quartz

February 27, 2021
NikolaNews

NikolaNews.com is an online News Portal which aims to share news about blockchain, AI, Big Data, and Data Privacy and more!

What’s New Here?

  • Cybercrime groups are selling their hacking skills. Some countries are buying February 28, 2021
  • Machine Learning May Reduce Mental Health Misdiagnosis February 28, 2021
  • Why would you ever trust Amazon’s Alexa after this? February 28, 2021
  • AI & ML Are Not Same. Here's Why – Analytics India Magazine February 27, 2021

Subscribe to get more!

© 2019 NikolaNews.com - Global Tech Updates

No Result
View All Result
  • AI Development
    • Artificial Intelligence
    • Machine Learning
    • Neural Networks
    • Learn to Code
  • Data
    • Blockchain
    • Big Data
    • Data Science
  • IT Security
    • Internet Privacy
    • Internet Security
  • Marketing
    • Digital Marketing
    • Marketing Technology
  • Technology Companies
  • Crypto News

© 2019 NikolaNews.com - Global Tech Updates