Information Security 11 min read

How to Securely Transmit and Store User Passwords: HTTPS, Encryption, and Bcrypt

This article explains why transmitting passwords over plain HTTP is unsafe, introduces HTTPS and its TLS encryption process, compares symmetric and asymmetric encryption methods, and recommends secure password storage techniques such as salted hashing and BCrypt to protect against rainbow‑table and brute‑force attacks.

macrozheng
macrozheng
macrozheng
How to Securely Transmit and Store User Passwords: HTTPS, Encryption, and Bcrypt

Preface

When developing a website or app, the first problem to solve is how to securely transmit and store user passwords . Data breaches at large companies show the severe impact of poor password handling, making this a fundamental skill for every programmer.

1. How to Securely Transmit User Passwords

To prevent passwords from traveling in clear text, we first consider the HTTPS protocol.

1.1 HTTPS Protocol

Three risks of HTTP

HTTP transmits data in plaintext, exposing three major risks: eavesdropping, data tampering, and identity spoofing. Therefore, passwords must be sent via HTTPS .

HTTPS principle

HTTPS = HTTP + SSL/TLS. SSL/TLS provides encryption, authentication, and integrity checks.

Below is a typical HTTPS request flow:

Client initiates an HTTPS request. Server presents a digital certificate (public/private key pair). Client verifies the certificate and generates a random symmetric key, encrypting it with the server’s public key. Client sends the encrypted symmetric key to the server. Server decrypts the symmetric key with its private key and uses it to encrypt response data. Server returns the encrypted data. Client decrypts the data with the symmetric key.

Is HTTPS always safe?

HTTPS can be compromised if the certificate is forged or a man‑in‑the‑middle attack succeeds, so additional measures are needed.

1.2 Symmetric Encryption

Even with HTTPS, encrypting the password before transmission adds another layer of protection. Symmetric encryption uses the same key for encryption and decryption.

Common symmetric algorithms include DES, 3DES, AES, etc.

When using symmetric encryption, the key exchange itself must be secure, otherwise the key can be intercepted.

1.3 Asymmetric Encryption

Asymmetric encryption uses a pair of keys: a public key for encryption and a private key for decryption.

Typical asymmetric algorithms include RSA, ECC, etc.

Example: Baidu’s login API provides a public key and uses the RSA algorithm (via the JavaScript library

jsencrypt

) to encrypt the password on the client side.

Thus, combining HTTPS with asymmetric encryption (e.g., RSA) provides a robust transmission method.

2. How to Securely Store Passwords

Once the password reaches the server, it must never be stored in plaintext. Instead, store a hash of the password.

A hash function generates a fixed‑size value from the input and cannot be reversed.

2.1 MD5 Hashing

MD5 is a classic hash algorithm but is insecure for passwords because of rainbow‑table attacks.

<code>public class MD5Test {
    public static void main(String[] args) {
        String password = "abc123456";
        System.out.println(DigestUtils.md5Hex(password));
    }
}
</code>

Result:

0659c7992e268962384eb17fafe88364

. This hash can be reversed using online databases.

2.2 MD5 + Salt

Adding a random salt to the password before hashing defeats rainbow‑table attacks.

Never hard‑code the salt; generate a unique, sufficiently long (e.g., >20 characters) random salt for each password. The salt should be stored alongside the hash.

2.3 BCrypt

BCrypt is a deliberately slow hashing algorithm designed for password storage, making brute‑force attacks costly.

Spring Security recommends BCryptPasswordEncoder over the deprecated MessageDigestPasswordEncoder .

Example comparison:

<code>public class BCryptTest {
    public static void main(String[] args) {
        String password = "123456";
        long md5Begin = System.currentTimeMillis();
        DigestUtils.md5Hex(password);
        long md5End = System.currentTimeMillis();
        System.out.println("md5 time:" + (md5End - md5Begin));
        long bcryptBegin = System.currentTimeMillis();
        BCrypt.hashpw(password, BCrypt.gensalt(10));
        long bcryptEnd = System.currentTimeMillis();
        System.out.println("bcrypt Time:" + (bcryptEnd - bcryptBegin));
    }
}
</code>
<code>md5 time:47
bcrypt Time:1597
</code>

BCrypt is dozens of times slower than MD5, greatly increasing attack cost.

3. Summary

Use HTTPS together with asymmetric encryption (e.g., RSA) to transmit passwords, optionally adding a client‑side random factor.

Store passwords with BCrypt and a unique salt.

When brute‑force risk is detected, enable additional defenses such as SMS verification, CAPTCHAs, or temporary account lockout.

EncryptionHashingpassword securityHTTPSbcrypt
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.