• Home
  • Categories
  • Recent
  • Popular
  • Pricing
  • Contact us
  • Docs
  • Login
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.
  • D
    dan
    last edited by dan 28 May 2020, 15:03

    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
    • D
      dan
      last edited by 28 May 2020, 15:04

      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
      • D
        dan
        last edited by 28 May 2020, 17:27

        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 17 Dec 2020, 19:48

          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