FusionAuth
    • Home
    • Categories
    • Recent
    • Popular
    • Pricing
    • Contact us
    • Docs
    • Login

    I've written a password encryption plugin I want to share. Where can I share it?

    Scheduled Pinned Locked Moved
    Q&A
    password plugin encryption
    1
    4
    1.8k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • danD
      dan
      last edited by dan

      I've written a plugin for a password encryption scheme that FusionAuth doesn't currently support. Where can I share that?

      --
      FusionAuth - Auth for devs, built by devs.
      https://fusionauth.io

      1 Reply Last reply Reply Quote 0
      • danD
        dan
        last edited by

        Please go ahead and add it to this topic.

        --
        FusionAuth - Auth for devs, built by devs.
        https://fusionauth.io

        1 Reply Last reply Reply Quote 0
        • danD
          dan
          last edited by

          There's a skeleton github repo.

          --
          FusionAuth - Auth for devs, built by devs.
          https://fusionauth.io

          1 Reply Last reply Reply Quote 0
          • P
            pclark
            last edited by

            In case it helps anyone, a version of the ASP.NET Core Identity PasswordHasher HashPasswordV3

            package com.mycompany.fusionauth.plugins;
            
            import javax.crypto.SecretKey;
            import javax.crypto.SecretKeyFactory;
            import javax.crypto.spec.PBEKeySpec;
            import java.nio.charset.StandardCharsets;
            import java.security.InvalidKeyException;
            import java.security.NoSuchAlgorithmException;
            import java.security.spec.InvalidKeySpecException;
            import java.security.spec.KeySpec;
            import java.util.Base64;
            import io.fusionauth.plugin.spi.security.PasswordEncryptor;
            
            /**
            * Example password hashing based on Asp.Net Core Identity PasswordHasher HashPasswordV3.
            */
            public class ExampleDotNetPBDKF2HMACSHA256PasswordEncryptor implements PasswordEncryptor {
            
              @Override
              public int defaultFactor() {
                return 10_000;
              }
            
              @Override
              public String encrypt(String password, String salt, int factor) {
                if (factor <= 0) {
                  throw new IllegalArgumentException("Invalid factor value [" + factor + "]");
                }
            
                SecretKeyFactory keyFactory;
                try {
                  keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
                } catch (NoSuchAlgorithmException e) {
                  throw new IllegalStateException("No such algorithm [PBKDF2WithHmacSHA256]");
                }
            
            	int keyLength = 32; // numBytesRequested
            	byte[] saltBytes = Base64.getDecoder().decode(salt); // assumes Base64 encoded salt. saltSize: 16 bytes
            
                KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, factor, keyLength * 8);
                SecretKey secret;
                try {
                  secret = keyFactory.generateSecret(keySpec); // subkey
                } catch (InvalidKeySpecException e) {
                  throw new IllegalArgumentException("Could not generate secret key for algorithm [PBKDF2WithHmacSHA256]");
                }
            	
            	byte[] outputBytes = new byte[13 + saltBytes.length + secret.getEncoded().length];
            	outputBytes[0] = 0x01; // format marker
            	WriteNetworkByteOrder(outputBytes, 1, 1);
            	WriteNetworkByteOrder(outputBytes, 5, factor);
            	WriteNetworkByteOrder(outputBytes, 9, saltBytes.length);
            	System.arraycopy(saltBytes, 0, outputBytes, 13, saltBytes.length);
            	System.arraycopy(secret.getEncoded(), 0, outputBytes, 13 + saltBytes.length, secret.getEncoded().length);
            	
            	return new String(Base64.getEncoder().encode(outputBytes));
              }
              
              private static void WriteNetworkByteOrder(byte[] buffer, int offset, int value)
              {
            	buffer[offset + 0] = (byte)(value >> 24);
            	buffer[offset + 1] = (byte)(value >> 16);
            	buffer[offset + 2] = (byte)(value >> 8);
            	buffer[offset + 3] = (byte)(value >> 0);
              }
            }
            
            package com.mycompany.fusionauth.plugins;
            
            import org.testng.annotations.DataProvider;
            import org.testng.annotations.Test;
            import static org.testng.Assert.assertEquals;
            
            public class ExampleDotNetPBDKF2HMACSHA256PasswordEncryptorTest {
              @Test(dataProvider = "hashes")
              public void encrypt(String password, String salt, String hash) {
                ExampleDotNetPBDKF2HMACSHA256PasswordEncryptor encryptor = new ExampleDotNetPBDKF2HMACSHA256PasswordEncryptor();
                assertEquals(encryptor.encrypt(password, salt, 10_000), hash);
              }
            
              @DataProvider(name = "hashes")
              public Object[][] hashes() {
                return new Object[][]{
                    {"MyExamplePassword", "CVsv6SwPJr7WDrVvAb+7aw==", "AQAAAAEAACcQAAAAEAlbL+ksDya+1g61bwG/u2ssOcnQU6Q2xo9tmijJv0zM2GsxeOl04NSpXRsAveBBag=="},
                };
              }
            }
            
            1 Reply Last reply Reply Quote 1
            • First post
              Last post