DevShivmohan / Learning-everything

Learning for developer only
0 stars 1 forks source link

Cryptography [Encryption and Decryption] #26

Open DevShivmohan opened 1 year ago

DevShivmohan commented 1 year ago

Asymetric Encryption/Decryption

Refer link - Asymetric cryptography

DevShivmohan commented 1 year ago

Generate encryption key in hex format in java

DatatypeConverter.printHexBinary(string_secret_variable.getBytes())

Implementation in JWT

package com.user.auth.util;

import com.user.auth.constant.ApiConstant;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

@Slf4j
@Component
public class JwtUtil {

    public static final String SECRET = "Shivmohan52415241$$56235fgfgfgfgfgh6212";

    public String extractUsername(String token) {
        return extractClaim(token, Claims::getSubject);
    }

    private Date extractExpiration(String token) {
        return extractClaim(token, Claims::getExpiration);
    }

    private  <T> T extractClaim(String token, Function<Claims, T> claimsResolver) {
        final Claims claims = extractAllClaims(token);
        return claimsResolver.apply(claims);
    }

    private Claims extractAllClaims(String token) {
        return Jwts
                .parserBuilder()
                .setSigningKey(getSignKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    private Boolean isTokenExpired(String token) {
        return extractExpiration(token).before(new Date());
    }

    private Boolean validateToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
    }

    public Boolean validateIsAccessToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token) && extractAllClaims(token).get(ApiConstant.TOKEN_TYPE).equals(ApiConstant.ACCESS_TOKEN));
    }

    public Boolean validateIsRefreshToken(String token, UserDetails userDetails) {
        final String username = extractUsername(token);
        return (username.equals(userDetails.getUsername()) && !isTokenExpired(token) && extractAllClaims(token).get(ApiConstant.TOKEN_TYPE).equals(ApiConstant.REFRESH_TOKEN));
    }

    public String generateAccessToken(String userName){
        Map<String,Object> claims=new HashMap<>();
        claims.put(ApiConstant.TOKEN_TYPE,ApiConstant.ACCESS_TOKEN);
        return createToken(claims,userName,12);
    }

    public String generateRefreshToken(String userName){
        Map<String,Object> claims=new HashMap<>();
        claims.put(ApiConstant.TOKEN_TYPE,ApiConstant.REFRESH_TOKEN);
        return createToken(claims,userName,24*7);
    }

    private String createToken(Map<String, Object> claims, String userName,long expiryTimeInHour) {
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(userName)
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis()+1000*60*60*expiryTimeInHour))
                .signWith(getSignKey(), SignatureAlgorithm.HS256).compact();
    }

    private Key getSignKey() {
        byte[] keyBytes= Decoders.BASE64.decode(DatatypeConverter.printHexBinary(SECRET.getBytes()));
        return Keys.hmacShaKeyFor(keyBytes);
    }
}
DevShivmohan commented 11 months ago

Use random hash key (Generate using Java) for JWT as a secret key upto 256 bit


import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class JwtSecretKeyGenerator {

    public static void main(String[] args) {
        int keyLengthInBytes = 256; // Change this to your desired key length in bytes
        String secretKey = generateRandomHexKey(keyLengthInBytes); // This secretKey is able to use in JWT as a secret key
        System.out.println("Generated Secret Key: " + secretKey);
    }

    public static String generateRandomHexKey(int keyLengthInBytes) {
        SecureRandom secureRandom;
        try {
            secureRandom = SecureRandom.getInstanceStrong(); // Use the strongest available algorithm
        } catch (NoSuchAlgorithmException e) {
            // Handle the exception, fallback to default algorithm or exit gracefully
            e.printStackTrace();
            return null;
        }

        byte[] keyBytes = new byte[keyLengthInBytes];
        secureRandom.nextBytes(keyBytes);

        // Convert bytes to hexadecimal string
        StringBuilder hexString = new StringBuilder();
        for (byte b : keyBytes) {
            hexString.append(String.format("%02x", b));
        }

        return hexString.toString().toUpperCase(); // Convert to uppercase for consistency (optional)
    }
}
DevShivmohan commented 7 months ago

To encrypt pdf using itextpdf library

dependency for gradle

    implementation 'com.itextpdf:itext7-core:7.2.1'

Code of block to encrypt the pdf

/**
     * To encrypt the pdf
     * @param inputFile
     * @throws IOException
     */
    public void encryptPdf(File inputFile) throws IOException {
        // Set the user and owner passwords
        String userPassword = "jasper123"; // User password (to open the PDF)
        String ownerPassword = "jasper123"; // Owner password (to change permissions)
        File outputFile=new File(inputFile.getParent()+File.separator+"_encrypted_"+inputFile.getName());
        PdfReader pdfReader = new PdfReader(inputFile);
        PdfWriter pdfWriter = new PdfWriter(outputFile.getAbsolutePath(),
                new WriterProperties().setStandardEncryption(userPassword.getBytes(),
                        ownerPassword.getBytes(), EncryptionConstants.ALLOW_PRINTING,
                        EncryptionConstants.ENCRYPTION_AES_256));
        // Create a PdfDocument instance
        PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter);
        // Close the PdfDocument to save changes
        pdfDocument.close();
        pdfWriter.flush();
        pdfWriter.close();
        System.out.println("Pdf encrypted");
    }