The source code for this blog is available on GitHub.
Note
Top

Cryptography

Cover Image for Cryptography
Han Chen
Han Chen

cryptography

In computer science, cryptography refers to secure information and communication techniques derived from mathematical concepts and a set of rule-based calculations called algorithms, to transform messages in ways that are hard to decipher.

Cryptography is closely related to the disciplines of cryptology and cryptanalysis. It includes techniques such as microdots, merging words with images and other ways to hide information in storage or transit. However, in today's computer-centric world, cryptography is most often associated with scrambling plaintext (ordinary text, sometimes referred to as cleartext) into ciphertext (a process called encryption), then back again (known as decryption). Individuals who practice this field are known as cryptographers.

Modern cryptography concerns itself with the following four objectives:

Noun Interpretation Translation
Confidentiality The information cannot be understood by anyone for whom it was unintended 機密性
Integrity The information cannot be altered in storage or transit between sender and intended receiver without the alteration being detected 完整性
Non-repudiation The creator/sender of the information cannot deny at a later stage their intentions in the creation or transmission of the information 不可否認性
Authentication The sender and receiver can confirm each other's identity and the origin/destination of the information 不可否認性

Cipher

A cipher (密碼) is an algorithm or method used in cryptography to perform encryption and decryption of data. It is a set of rules and operations that transform plaintext (original message) into ciphertext (encrypted message) and vice versa.

In the context of cryptography, a cipher typically involves substituting or transposing characters or bits according to a specific rule or algorithm. The purpose of a cipher is to ensure the confidentiality and integrity of information by making it unintelligible to unauthorized individuals.

A cipher refers to an algorithm or method used in encryption and decryption processes. It is a set of rules or instructions that dictate how plaintext (unencrypted data) is transformed into ciphertext (encrypted data) and vice versa.

Classification

Ciphers can be classified into different categories based on their properties and characteristics. Here are a few common types of ciphers:

  1. ✅ Symmetric Ciphers: These ciphers use the same key for both encryption and decryption. Examples include the Advanced Encryption Standard (AES) and Data Encryption Standard (DES).
  2. ✅ Asymmetric Ciphers: Also known as public-key cryptography, these ciphers use a pair of mathematically related keys: a public key for encryption and a private key for decryption. Examples include RSA and Elliptic Curve Cryptography (ECC).
  3. ❌ Block Ciphers: These ciphers operate on fixed-size blocks of plaintext at a time and encrypt them into corresponding blocks of ciphertext. AES is an example of a block cipher.
  4. ❌ Stream Ciphers: These ciphers encrypt plaintext and produce ciphertext one bit or one byte at a time. They typically involve the use of a keystream generated from a key. The RC4 cipher is a well-known stream cipher.

Ciphers play a vital role in securing sensitive information, protecting privacy, and ensuring the confidentiality and integrity of data. Different ciphers have varying levels of complexity and security, and the choice of cipher depends on the specific requirements and use case

Decipher

Decipher, in the context of cryptography, refers to (破譯在密碼學中指的是 ...) the process of decrypting or decoding encrypted or encoded information. It involves reversing the encryption process to convert the ciphertext (encrypted data) back into its original plaintext form.

Cipheriv

Symmetric Encryption

Symmetric encryption, also known as symmetric-key cryptography or shared-key cryptography, is a fundamental concept in modern cryptography.

In symmetric encryption, the same key is used for both the encryption and decryption processes. This means that the sender and receiver share a common secret key, which must be kept confidential to ensure secure communication. The symmetric-key algorithm applies mathematical operations to transform the plaintext into ciphertext, and vice versa, providing confidentiality and integrity to the data. Symmetric encryption is known for its efficiency and speed, making it suitable for applications where performance is critical. However, the challenge lies in securely exchanging the secret key between the communicating parties. Once the key is compromised (一但要是被洩漏以後), the confidentiality of the encrypted data is at risk. To address this, secure key exchange protocols and key management practices are employed to protect the shared key and ensure the ongoing security of symmetric encryption systems.

AES

Here's a simple example of symmetric encryption and decryption using JavaScript

// Import the CryptoJS library (make sure it's installed)
const CryptoJS = require("crypto-js");

// Function to encrypt a message using a secret key
function encryptMessage(message, secretKey) {
  const encrypted = CryptoJS.AES.encrypt(message, secretKey).toString();
  return encrypted;
}

// Function to decrypt an encrypted message using the secret key
function decryptMessage(encryptedMessage, secretKey) {
  const decryptedBytes = CryptoJS.AES.decrypt(encryptedMessage, secretKey);
  const decrypted = decryptedBytes.toString(CryptoJS.enc.Utf8);
  return decrypted;
}

// Example usage
const secretKey = "your-secret-key";
const message = "Hello, World!";

// Encrypt the message
const encryptedMessage = encryptMessage(message, secretKey);
console.log("Encrypted message:", encryptedMessage);

// Decrypt the message
const decryptedMessage = decryptMessage(encryptedMessage, secretKey);
console.log("Decrypted message:", decryptedMessage);

using cipheriv is a more secure approach for symmetric encryption compared to the example I provided earlier. cipheriv allows you to specify an initialization vector (IV), which adds an additional layer of randomness and security to the encryption process.

In practice, the same IV should be used for both encryption and decryption to ensure the successful decryption of the message. The IV is not meant to be kept secret and can be transmitted alongside the encrypted message.

Here's an updated example with the same IV for encryption and decryption:

// Import the CryptoJS library (make sure it's installed)
const CryptoJS = require("crypto-js");

// Function to encrypt a message using a secret key and IV
function encryptMessage(message, secretKey, iv) {
  const cipher = CryptoJS.AES.encrypt(message, secretKey, { iv: iv });
  const encrypted = cipher.toString();
  return encrypted;
}

// Function to decrypt an encrypted message using the secret key and IV
function decryptMessage(encryptedMessage, secretKey, iv) {
  const decrypted = CryptoJS.AES.decrypt(encryptedMessage, secretKey, { iv: iv });
  return decrypted.toString(CryptoJS.enc.Utf8);
}

// Example usage
const secretKey = "your-secret-key";
const message = "Hello, World!";
const iv = CryptoJS.lib.WordArray.random(16); // Generate a random IV

// Encrypt the message
const encryptedMessage = encryptMessage(message, secretKey, iv);
console.log("Encrypted message:", encryptedMessage);

// Decrypt the message
const decryptedMessage = decryptMessage(encryptedMessage, secretKey, iv);
console.log("Decrypted message:", decryptedMessage);

Triple DES

Here's an example of using the Triple DES (3DES) algorithm for encryption and decryption in JavaScript:

// Import the CryptoJS library (make sure it's installed)
const CryptoJS = require("crypto-js");

// Function to encrypt a message using a secret key
function encryptMessage(message, secretKey) {
  const encrypted = CryptoJS.TripleDES.encrypt(message, secretKey).toString();
  return encrypted;
}

// Function to decrypt an encrypted message using the secret key
function decryptMessage(encryptedMessage, secretKey) {
  const decryptedBytes = CryptoJS.TripleDES.decrypt(encryptedMessage, secretKey);
  const decrypted = decryptedBytes.toString(CryptoJS.enc.Utf8);
  return decrypted;
}

// Example usage
const secretKey = "your-secret-key";
const message = "Hello, World!";

// Encrypt the message
const encryptedMessage = encryptMessage(message, secretKey);
console.log("Encrypted message:", encryptedMessage);

// Decrypt the message
const decryptedMessage = decryptMessage(encryptedMessage, secretKey);
console.log("Decrypted message:", decryptedMessage);

AES and 3DES

Let's explore AES (Advanced Encryption Standard) and 3DES (Triple Data Encryption Standard), two advanced encryption algorithms widely used for securing sensitive information.

  1. AES (Advanced Encryption Standard): AES is a symmetric encryption algorithm that has become the de facto standard for encryption worldwide. It was selected by the National Institute of Standards and Technology (NIST) in 2001 to replace the aging Data Encryption Standard (DES). AES employs a block cipher that operates on fixed-size blocks of data.

Key Features:

  • Block Size: AES operates on 128-bit blocks of data.
  • Key Size: It supports three key sizes: 128-bit, 192-bit, and 256-bit.
  • Number of Rounds: The number of encryption rounds varies based on the key size (10 rounds for 128-bit key, 12 rounds for 192-bit key, and 14 rounds for 256-bit key).
  • Security: AES is considered highly secure and resistant to attacks when used properly.
  1. 3DES (Triple Data Encryption Standard): 3DES is a symmetric encryption algorithm that is a variant of the original DES. It applies the DES algorithm three times to each data block to increase security. 3DES was developed to provide enhanced security over the aging DES algorithm.

Key Features:

  • Block Size: 3DES operates on 64-bit blocks of data.
  • Key Size: It uses key sizes of 128 bits, of which only 112 bits are considered effective, as the remaining bits are used for parity checks.
  • Number of Rounds: It applies the DES algorithm three times, with each round using a different key.
  • Security: While 3DES has been widely used in the past, it is considered relatively slower and less secure compared to AES.

Comparing AES and 3DES:

  • Security: AES is generally considered more secure than 3DES due to its larger key sizes and increased number of rounds.
  • Speed: AES is typically faster than 3DES in terms of encryption and decryption speed.
  • Key Size: AES supports multiple key sizes (128-bit, 192-bit, and 256-bit), while 3DES has a fixed key size of 128 bits (effectively 112 bits).

Overall, AES is widely adopted as a highly secure encryption algorithm for various applications, including data protection, network communication, and secure storage. While 3DES still has some legacy uses, it has largely been phased out in favor of AES due to its slower performance and perceived vulnerabilities.

It's worth noting that proper implementation and key management are critical for maintaining the security of any encryption algorithm.

Asymmetric Encryption

Asymmetric encryption is a cryptographic approach that employs a pair of mathematically related keys: a public key and a private key. Unlike symmetric encryption, where the same key is used for both encryption and decryption, asymmetric encryption involves the use of different keys for these operations.

The public key, as the name suggests, is publicly available and can be freely distributed. It is used to encrypt data or messages intended for a specific recipient. The private key, on the other hand, is kept securely by the intended recipient and is used for decrypting the encrypted data.

One of the primary advantages of asymmetric encryption is its ability to establish secure communication channels between two parties who have never directly interacted before. This is achieved through a fascinating property: anything encrypted with a recipient's public key can only be decrypted with their corresponding private key. This property ensures confidentiality and authenticity of the exchanged information.

Digital Signatures

Digital signatures are cryptographic mechanisms used to provide authenticity, integrity, and non-repudiation(不可否認) to electronic documents, messages, or data. They serve as a digital equivalent of handwritten signatures or seals in the physical world.

A digital signature is created using asymmetric encryption techniques. It involves the use of the signer's private key to generate a unique mathematical representation, or signature, of the data being signed. This signature is appended to the document or message, along with the signer's public key.

Block Cipher and Stream Cipher

The following are the categories which are hard to make out

Term
Block Cipher A block cipher is a type of symmetric encryption algorithm that operates on fixed-size blocks of plaintext at a time and transforms them into corresponding blocks of ciphertext. The plaintext is divided into fixed-size blocks, usually 64 or 128 bits, and each block is independently encrypted. Block ciphers use a cryptographic key to determine the encryption process and are typically designed to be secure against various attacks.
Stream Cipher A stream cipher is another type of symmetric encryption algorithm that encrypts and decrypts data one bit or one byte at a time. Instead of dividing the data into fixed blocks, a stream cipher operates on a continuous stream of data. Stream ciphers generate a keystream, which is a series of pseudorandom bits or bytes, by using a cryptographic key and an initialization vector (IV). The keystream is then combined with the plaintext using an XOR operation to produce the ciphertext.

The Advanced Encryption Standard (AES) is a widely used block cipher algorithm. It supports different key sizes, such as AES-128, AES-192, and AES-256, and is considered secure and efficient for various cryptographic applications.

The RC4 cipher, although historically popular, is an example of a stream cipher. However, it has known security vulnerabilities and is no longer recommended for use in modern cryptographic systems. Other stream ciphers, such as Salsa20 and ChaCha20, are considered more secure and widely adopted.

Both block ciphers and stream ciphers are used to achieve secure communication and data protection. The choice between them depends on factors such as the specific requirements of the application, performance considerations, and the desired properties of the encryption algorithm.

Javascript - Buffer from string

In JavaScript and TypeScript, Buffer.from is a method used to create a new Buffer object from a given input. The Buffer class provides a way to work with binary data in Node.js and some web browsers.

The Buffer.from method can be used in different ways depending on the type of input you provide. Here are a few examples:

  1. Creating a Buffer from a string:
const str = 'Hello, World!';
const buffer = Buffer.from(str, 'utf8');
  1. Creating a Buffer from an array of integers:
const arr = [72, 101, 108, 108, 111];
const buffer = Buffer.from(arr); 
// <Buffer 48 65 6c 6c 6f>
  1. Creating a Buffer from a hexadecimal string:
const hexString = '48656c6c6f2c20576f726c6421';
const buffer = Buffer.from(hexString, 'hex');

The second argument to Buffer.from is optional and specifies the encoding of the input. Common encodings include 'utf8', 'hex', 'base64', and others.

Once you have created a Buffer using Buffer.from, you can perform various operations on it, such as reading or modifying its content, converting it to different formats, or using it in cryptographic operations.

Note that Buffer is a Node.js-specific class, so it may not be available in all JavaScript environments, such as web browsers. In web browsers, you can use TextEncoder and TextDecoder APIs to work with binary data.

Hex and Base64

Hexadecimal (hex) and Base64 are both encoding schemes used to represent binary data in a human-readable format. The key differences between hex and Base64 are as follows

  1. Representation: Hexadecimal encoding represents binary data using a combination of 16 distinct characters (0-9, A-F). Each byte of binary data is represented by two characters, allowing a direct one-to-one mapping between binary and hex values.
  2. Character Set: Base64 encoding uses a set of 64 characters [ A-Z, a-z, 0-9, +, /, and sometimes = as a padding character ] to represent binary data. It uses a grouping mechanism where each set of 3 bytes (24 bits) of binary data is represented by 4 characters.
    • In the context of encoding schemes like Base64, a padding character is used to ensure that the encoded data has a length that is a multiple of a certain number of characters.
    • In Base64 encoding, the data is divided into groups of three bytes (24 bits), and each group is represented by four characters. However, if the length of the data is not a multiple of three bytes, padding is added to make the length a multiple of three.
    • The string "Hello" is encoded in Base64 as "SGVsbG8=". Here, the equals sign (=) serves as the padding character, indicating that the original data had only five characters.
    • In the context of programming and data processing, "pad" refers to the act of adding additional characters or values to align or adjust the length of a string or data structure. It is commonly used to ensure that data meets certain requirements or conforms to a specific format.
    • When we talk about "padding" (填充) in a literal sense, it means adding extra characters or values to fill in space.
    • Padding can serve different purposes, such as achieving a desired length, aligning data, or meeting specific formatting requirements. The added characters are typically chosen to be neutral or insignificant in terms of their impact on the overall data.
  3. Efficiency: Base64 encoding is more space-efficient compared to hex encoding. In Base64, each character represents 6 bits of data, while in hex, each character represents 4 bits of data. Therefore, Base64 requires fewer characters to represent the same amount of data.
  4. Readability: Hex encoding is more readable for humans since it directly represents the binary data using familiar hexadecimal digits. Base64 encoding, on the other hand, uses a wider range of characters, making it less intuitive to read.

The Buffer.from() method in JavaScript allows us to create a buffer object from a given input, which can be a string, array, or even a number. By applying the .toString('base64') method on the buffer object, we can obtain the Base64 encoding of the input value.

Let's examine a few examples:

  1. Buffer.from('2').toString('base64'): Output: "Mg==" Explanation: The input value is the string "2". When encoded in Base64, it results in "Mg==".
  2. Buffer.from('22').toString('base64'): Output: "MjI=" Explanation: The input value is the string "22". When encoded in Base64, it results in "MjI=".
  3. Buffer.from('222').toString('base64'): Output: "MjIy" Explanation: The input value is the string "222". When encoded in Base64, it results in "MjIy".
  4. Buffer.from('2222').toString('base64'): Output: "MjIyMg==" Explanation: The input value is the string "2222". When encoded in Base64, it results in "MjIyMg==".

JWT

JWT (JSON Web Token) is not a form of symmetric encryption. JWT is a compact, URL-safe means of representing claims between two parties in the form of a JSON object. It is commonly used for authentication and authorization purposes in web applications.

JWT itself does not involve encryption. Instead, it uses a combination of digital signatures or HMAC (Hash-based Message Authentication Code) to ensure the integrity and authenticity of the information contained within the token.

When a JWT is created, the token is composed of three parts: the header, the payload (claims), and the signature. The header and payload are JSON objects that contain the relevant information, such as the token's issuer, expiration time, and other user-defined claims. **The signature, which is the third part of the JWT, is created by hashing the concatenation of the base64-encoded header and payload along with a secret key using a cryptographic algorithm like HMAC or RSA **

  • signature 是JWT的第三部分,透過使用HMAC或RSA等加密演算法將base64編碼的頭和有效負載的連線以及金鑰雜湊來建立。
  • concatenation refers to the process of combining two or more strings, arrays, or other data structures to create a single entity. In the context of hashing, concatenation refers to joining multiple data elements together in a specific order before applying the hash function.

The key difference between symmetric encryption and JWT is that symmetric encryption uses a shared secret key for both encryption and decryption, whereas JWT relies on digital signatures or HMAC to verify the integrity of the token without involving encryption. The token's integrity can be validated using the secret key on the receiving end, ensuring that the token has not been tampered with during transmission.

So, JWT is not a form of symmetric encryption but a token-based mechanism that relies on digital signatures or HMAC to provide data integrity and authenticity in a secure manner.

In JWT, the secret key is used to sign the token, which involves cryptographic operations, but it is not used for encryption and decryption. JWT uses digital signatures or HMAC to ensure the integrity and authenticity of the token, but it does not involve encryption of the token's payload.

Question: How does JWT reverse the second part to an actual data

JWT does not reverse the second part of the token (payload) to its original form. The second part of the JWT, which is the payload, contains the claims or information embedded within the token. These claims are typically represented as a JSON object.

Once the JWT is created, the payload is encoded using a specific algorithm (e.g., Base64) to convert it into a compact, URL-safe string representation. This encoding is not encryption; it is a reversible encoding that ensures the payload can be efficiently transmitted as a string.

When a recipient receives a JWT, it can decode the second part (payload) using the same encoding algorithm to obtain the original JSON representation of the claims. This decoding operation reverses the encoding process, converting the encoded string back into the original JSON object.

In JWT, the secret key is required to verify the integrity and authenticity of the token. It is used to verify the signature or HMAC of the token, which is part of the third section of the JWT.

The third section of a JWT is the signature, which is created by signing the concatenated first two sections (header and payload) using the secret key. The signature provides assurance that the token has not been tampered with and that it was indeed issued by the trusted party.

When a recipient receives a JWT, it can validate the token by performing the following steps:

  1. Decode the JWT: The recipient decodes the JWT to extract the header and payload sections.
  2. Verify the Signature: The recipient then takes the decoded header and payload sections, re-computes the signature by using the same algorithm and the shared secret key, and compares it to the signature in the token. If the calculated signature matches the received signature, the token's integrity is confirmed.

By verifying the signature using the shared secret key, the recipient ensures that the token has not been modified or tampered with. If the signature validation fails, it indicates that the token may have been tampered with, and it should be rejected.

Hashing Data

Hashing data refers to the process of taking an input (such as a message, file, or piece of data) and using a hashing algorithm to transform it into a fixed-size, unique string of characters called a hash value or hash code. The hash value is typically a sequence of alphanumeric characters that represents the original data in a condensed and irreversible form.

Hashing Function

A hashing algorithm, also known as a hash function, is a mathematical function specifically designed to generate a unique hash value for a given input. The goal of a hashing algorithm is to produce a hash code that is deterministic (the same input will always produce the same hash) and provides a high level of collision resistance (it should be computationally infeasible to find two different inputs that produce the same hash).

for a given hash function, the same input will always produce the same hash output. This is a fundamental property of hash functions.

This is because a hash function, like SHA-1 or SHA-256, is a deterministic process: it operates the same way each time it is run, and its output is determined entirely by its input. If you give it the same input, it will produce the same output.

When you hash data (for example, a password), you can't get the original data back from the hash. Instead, you typically use hashes to check if the same data is entered again later.

Hashing algorithms are widely used in various applications, including data integrity checks, password storage, digital signatures, data indexing, and more. Some commonly used hashing algorithms include:

  • MD5 (Message Digest Algorithm 5)
  • SHA-1 (Secure Hash Algorithm 1)
  • SHA-256 (Secure Hash Algorithm 256-bit)

The first widely used hashing algorithms were the MD (Message Digest), it was replaced by MD2, MD3, MD4 and finally MD5, which was first broken at the beginning of this century (here is a demonstration of that weakness: https://www.mscs.dal.ca/~selinger/md5collision/). Then the SHA1 (Secure Hash Algorithm) was created based on MD4, and was broken too (here you can check some vulnerabilities: https://shattered.io/). Currently we use SHA2, which is a family of algorithms able to produce hashes of 224, 256, 384 or 512 bits. All the most important cryptographic systems today work using the security of SHA2!

Hash functions are used in almost all crypto systems. Also there are some uses which are not related with encryption

  • git uses SHA1 over the parameters and body of one commit to act as a kind of commit reference.
  • Bitcoin uses SHA2 in 256 mode to hash the entire block of transactions twice appending a nonce (an arbitrary data) in order to ensure a proof of work. When storing passwords within a database, it is a must to store the password hashed and not as plain text.

The main characteristics and uses of hashing algorithms are:

  1. Deterministic: The same input will always produce the same hash value, allowing for data verification and comparison.

  2. Irreversible: It is computationally infeasible (計算不可行) to obtain the original data from its hash value alone, ensuring data integrity and security.

    👉 Most hashing algorithms do not involve padding as part of the hashing process itself. Instead, they operate on the input data directly and produce a hash value of a predetermined length.

    👉 For example:

    • MD5 produces a 128-bit (16-byte) hash value.
    • SHA-1 produces a 160-bit (20-byte) hash value.
    • SHA-256 produces a 256-bit (32-byte) hash value.
  3. Fixed-size output: Hashing algorithms produce hash values of a fixed size, regardless of the size of the input. 固定大小的輸出:散列演算法產生固定大小的散列值,無論輸入的大小如何。

  4. Collision resistance: Hashing algorithms should make it highly improbable to find two different inputs that produce the same hash value. 抗碰撞性:雜湊演算法應該使找到產生相同雜湊值的兩個不同輸入變得非常不可能。

By generating unique hash values for data, hashing algorithms enable data integrity checks and provide a means to quickly verify if data has been tampered with or modified. They are widely used in data security and cryptographic applications to ensure data authenticity, integrity, and non-repudiation.

What are the differences between SHA, MD5, and SHA256?

The main differences between SHA, MD5, and SHA256 are the output length, the security level, and the performance. SHA has several variants, such as SHA-1, SHA-2, and SHA-3, each with different output lengths and security levels. SHA-1 produces a 160-bit output, SHA-2 produces a 224, 256, 384, or 512-bit output, and SHA-3 produces a 224, 256, 384, or 512-bit output. MD5 produces a 128-bit output, and SHA256 produces a 256-bit output. Generally, the longer the output, the more secure the hash function, as it reduces the chances of collisions (two different inputs producing the same output). However, the longer the output, the more computational resources and time required to generate and process the hash. Therefore, there is a trade-off between security and performance.

MD5

MD5 (Message Digest Algorithm 5) is a widely used cryptographic hash function that produces a 128-bit (16-byte) hash value. It is commonly used to verify data integrity.

MD5 has been utilized in a wide variety of security applications and is also commonly used to check the integrity of downloaded files. However, MD5 is not collision-resistant; as of 2021, it is possible to generate different inputs that hash to the same output, which makes it unsuitable for functions such as SSL certificates or encryption that require a unique output. Moreover, MD5 is considered to be broken and unsuitable for further use.

Despite these vulnerabilities, MD5 remains in use for non-cryptographic purposes, such as checksums for file integrity verification, where the vulnerabilities do not present a serious risk.

// Create an MD5 hash of the data
let hash = crypto.createHash('md5').update(data).digest('hex');
console.log(hash); // 720efffa2ad837b621b385f4003b4aee

SHA

SHA-256 is a member of the SHA-2 (Secure Hash Algorithm 2) family. The SHA-2 family consists of six hash functions with digest sizes of 224, 256, 384, 512, 512/224, and 512/256 bits.

SHA-256, specifically, generates a hash that is 256 bits in length. It's commonly used because it provides a good balance between security and performance. But for more sensitive information, you might use SHA-384 or SHA-512, which generate even longer (and thus more secure) hashes.

In general, the choice between different members of the SHA-2 family (or SHA-3, for that matter) will depend on your specific security needs and performance considerations.

const crypto = require('crypto-js');

function storePassword(userPassword) {
  // Hash the password and store it
  return crypto.SHA256(userPassword).toString();
}

function checkPassword(inputPassword, storedHashedPassword) {
  // Hash the password entered by the user
  let hashedInputPassword = crypto.SHA256(inputPassword).toString();

  // Compare the hashed input with the stored hash
  if (hashedInputPassword === storedHashedPassword) {
    return 'Password is correct.'
  } else {
    return 'Password is incorrect.'
  }
}

// Example usage:
let storedHashedPassword = storePassword('myPassword');

const qq = checkPassword('myPassword', storedHashedPassword);  // Outputs: Password is correct.
const ww = checkPassword('wrongPassword', storedHashedPassword);  // Outputs: Password is incorrect.
console.log({ qq, ww })

Here's how you might use a hash in the context of storing passwords:

  1. When a user creates an account or changes their password, you don't store their actual password. Instead, you hash the password and store the hash.
  2. Later, when the user tries to log in, they enter their password again. You hash the password they entered and compare it with the stored hash.
  3. If the hashes match, the password they entered is correct, and you can let them log in. If the hashes don't match, the password they entered is incorrect.

Yes, the SHA series of hash functions are designed to be collision-resistant, but it's important to note that this doesn't mean they're immune to collisions. Collision-resistance means that it's computationally difficult (ideally, practically impossible) to find two different inputs that produce the same hash output.

SHA-1, for example, was originally designed to be collision-resistant, but as of 2021, researchers have discovered practical collision attacks against it, which is why it's no longer recommended for most cryptographic purposes.

SHA-2, which includes SHA-256 and SHA-512 among others, is currently considered to be collision-resistant, and is widely used for cryptographic purposes.

SHA-3, the most recent member of the SHA family, is also designed to be collision-resistant, and has some security properties that make it a good choice even as we move towards a world with quantum computers.

However, the security of these functions is an ongoing area of research, and what's considered secure can change as new attacks are discovered and as computational power continues to increase. That's why it's important to stay updated on the latest recommendations and best practices in cryptography. As of my knowledge cutoff in September 2021, SHA-256 and SHA-3 are generally good choices for a hash function in terms of collision resistance.

checksum

a checksum is a value that is computed from a data set and is used for error checking. It's a simple way to verify the integrity of data.

Here are some common use cases for checksums:

  1. File Integrity Verification: One of the most common uses of checksums is in file integrity verification. For example, when you download a file from the internet, the website might provide a checksum for the file. You can compute the checksum for the downloaded file on your own machine and compare it to the one provided by the website. If the two match, you can be confident that the file was not altered or corrupted during the download process.
  2. Data Transmission Error Detection: Checksums are often used in network protocols to detect errors in data transmission. For example, when a packet of data is sent over a network, a checksum of the packet might be calculated and sent along with it. The recipient can then calculate the checksum for the received packet and compare it to the received checksum. If they don't match, it indicates that the packet was corrupted during transmission.
  3. Disk Error Detection: Checksums can also be used to verify the integrity of data stored on disk. For example, a filesystem might calculate a checksum for each block of data written to disk. When a block is read back, its checksum is calculated again and compared to the stored value to verify the data hasn't been corrupted.

In all of these use cases, checksums provide a simple and efficient way to verify that data has not been unintentionally altered. However, checksums like those calculated using the MD5 hash function are not secure against intentional tampering, so they should not be relied upon for cryptographic security.

How do you choose between SHA, MD5, and SHA256?

The choice of hash function depends on the context and the requirements of the application. For example, if you need to ensure the highest level of security and compliance, you should use SHA-2 or SHA-3, as they are the most robust and widely accepted standards. If you need to optimize the speed and efficiency of the hashing process, you might use MD5 or SHA-1, as they are faster and simpler than SHA-2 or SHA-3. However, you should be aware of the risks and limitations of using these older algorithms, as they are vulnerable to attacks and collisions. For example, MD5 is not recommended for cryptographic purposes, as it can be easily cracked and forged. SHA-1 is also deprecated by NIST, as it has been shown to have collisions and weaknesses. SHA256 is a good compromise between security and performance, as it offers a high level of resistance to attacks and collisions, while being relatively fast and easy to implement.

Reference

© 2024 WOOTHINK. All Rights Reserved.
Site MapTerms and ConditionsPrivacy PolicyCookie Policy