From a071cb573257d839e5083c569e831e226aa78e65 Mon Sep 17 00:00:00 2001 From: Joern Muehlencord Date: Thu, 12 Sep 2019 23:43:14 +0200 Subject: [PATCH] updated license header, merged shared-security --- util/pom.xml | 5 +- .../java/de/muehlencord/shared/util/Luhn.java | 66 +++++++++++++++ .../muehlencord/shared/util/PasswordUtil.java | 83 +++++++++++++++++++ .../shared/util/SecurityException.java | 41 +++++++++ .../de/muehlencord/shared/util/file/BOM.java | 2 +- .../util/file/BOMStripperInputStream.java | 2 +- .../muehlencord/shared/util/DefaultTest.java | 22 +++-- .../de/muehlencord/shared/util/LuhnTest.java | 61 ++++++++++++++ .../muehlencord/shared/util/OSUtilTest.java | 22 +++-- .../shared/util/PasswordUtilTest.java | 59 +++++++++++++ .../util/StringEncodingExceptionTest.java | 22 +++-- .../shared/util/StringUtilTest.java | 22 +++-- .../shared/util/file/FileUtilTest.java | 22 +++-- 13 files changed, 366 insertions(+), 63 deletions(-) create mode 100644 util/src/main/java/de/muehlencord/shared/util/Luhn.java create mode 100644 util/src/main/java/de/muehlencord/shared/util/PasswordUtil.java create mode 100644 util/src/main/java/de/muehlencord/shared/util/SecurityException.java create mode 100644 util/src/test/java/de/muehlencord/shared/util/LuhnTest.java create mode 100644 util/src/test/java/de/muehlencord/shared/util/PasswordUtilTest.java diff --git a/util/pom.xml b/util/pom.xml index 2ccd0b6..6459dfa 100644 --- a/util/pom.xml +++ b/util/pom.xml @@ -18,7 +18,6 @@ http://maven.apache.org UTF-8 - gpl20 @@ -32,5 +31,9 @@ slf4j-api provided + + org.bouncycastle + bcprov-jdk15on + diff --git a/util/src/main/java/de/muehlencord/shared/util/Luhn.java b/util/src/main/java/de/muehlencord/shared/util/Luhn.java new file mode 100644 index 0000000..3850334 --- /dev/null +++ b/util/src/main/java/de/muehlencord/shared/util/Luhn.java @@ -0,0 +1,66 @@ +/* + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.muehlencord.shared.util; + +import static java.lang.Integer.parseInt; +import static java.lang.String.valueOf; + +/** + * + * @author Joern Muehlencord (joern@muehlencord.de) + */ +public class Luhn { + + public static boolean validateNumber(final String numberStr) { + return (computeCheckDigit(numberStr, true) == 0); + } + + public static int computeCheckDigit(final String numberStr, final boolean isCheckDigitAttached) { + boolean doubleNextDigit = !isCheckDigitAttached; + int sum = 0; + + // iterate from right digit to left + for (int currentDigitPos = numberStr.length() - 1; currentDigitPos >= 0; currentDigitPos--) { + int currentDigit = parseInt(valueOf(numberStr.charAt(currentDigitPos))); + if (doubleNextDigit) { + currentDigit = currentDigit * 2; + } + sum += singleDigitSum(currentDigit); + doubleNextDigit = !doubleNextDigit; + } + + if ((sum % 10) > 0) { + return (10 - (sum % 10)); + } else { + return 0; + } + } + + private static int singleDigitSum(final int value) { + if (value < 10) { + return value; + } else { + return singleDigitSum((value / 10) + (value % 10)); + } + } +} + +/** + * History: + * + * $$Log$$ + * + */ diff --git a/util/src/main/java/de/muehlencord/shared/util/PasswordUtil.java b/util/src/main/java/de/muehlencord/shared/util/PasswordUtil.java new file mode 100644 index 0000000..87f26da --- /dev/null +++ b/util/src/main/java/de/muehlencord/shared/util/PasswordUtil.java @@ -0,0 +1,83 @@ +/* + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.muehlencord.shared.util; + +import java.security.SecureRandom; +import org.bouncycastle.crypto.generators.SCrypt; +import org.bouncycastle.util.encoders.Base64; + +/** + * + * @author Joern Muehlencord (joern@muehlencord.de) + */ +public class PasswordUtil { + + private final static SecureRandom SECURERANDOM = new SecureRandom(); + + private final static int CPU_MEMORY_COST_PARAMETER = 16384; + private final static int BLOCK_SIZE = 8; + private final static int PARALLELIZATION = 1; + private final static int KEY_LENGTH = 32; + + private final String systemsalt; + + public PasswordUtil(String systemSaltBase64Coded) { + // TODO make some tests like lengths etc + this.systemsalt = systemSaltBase64Coded; + } + + public String getHash(String clearPassword) { + + // generate user salt + byte[] userSaltBytes = new byte[32]; + SECURERANDOM.nextBytes(userSaltBytes); + String userSalt = new String(Base64.encode(userSaltBytes)); + + // create passwordhash with salt + String passwordHash = getPasswordHash(systemsalt, userSalt, clearPassword); + + StringBuilder sb = new StringBuilder(); + sb.append(userSalt); + sb.append(":"); + sb.append(passwordHash); + + return sb.toString(); + } + + public boolean matches(String clearPassword, String passwordHashWithSalt) { + if (!passwordHashWithSalt.contains(":")) { + // TODO add exception handling + return false; + } + + String userSalt = passwordHashWithSalt.substring(0, passwordHashWithSalt.indexOf(":")); + String passwordHash = passwordHashWithSalt.substring(passwordHashWithSalt.indexOf(":")+1); + + String validationHash = getPasswordHash(systemsalt, userSalt, clearPassword); + return validationHash.equals(passwordHash); + } + + private String getPasswordHash(String systemSaltBase64, String userSaltBase64, String clearPassword) { + byte[] systemSalt = systemSaltBase64.getBytes(); + byte[] userSalt = userSaltBase64.getBytes(); + byte[] salt = new byte[systemSalt.length + userSalt.length]; + + System.arraycopy(systemSalt, 0, salt, 0, systemSalt.length); + System.arraycopy(userSalt, 0, salt, systemSalt.length, userSalt.length); + + return new String(Base64.encode(SCrypt.generate(clearPassword.getBytes(), salt, CPU_MEMORY_COST_PARAMETER, BLOCK_SIZE, PARALLELIZATION, KEY_LENGTH))); + } +} diff --git a/util/src/main/java/de/muehlencord/shared/util/SecurityException.java b/util/src/main/java/de/muehlencord/shared/util/SecurityException.java new file mode 100644 index 0000000..e290c53 --- /dev/null +++ b/util/src/main/java/de/muehlencord/shared/util/SecurityException.java @@ -0,0 +1,41 @@ +/* + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.muehlencord.shared.util; + +/** + * + * @author joern@muehlencord.de + */ +public class SecurityException extends Exception { + + public SecurityException() { + super ("An error occured during a security action"); + } + + public SecurityException(String msg) { + super (msg); + } + + public SecurityException(String msg, Throwable cause) { + super(msg, cause); + } + + public SecurityException(Throwable cause) { + super (cause); + } + + +} diff --git a/util/src/main/java/de/muehlencord/shared/util/file/BOM.java b/util/src/main/java/de/muehlencord/shared/util/file/BOM.java index 8d13ec9..01414bb 100644 --- a/util/src/main/java/de/muehlencord/shared/util/file/BOM.java +++ b/util/src/main/java/de/muehlencord/shared/util/file/BOM.java @@ -24,7 +24,7 @@ import java.util.Map; * Defines possbile file Byte Order Marks used in files. * * @see http://en.wikipedia.org/wiki/Byte-order_mark - * @author joern.muehlencord + * @author Joern Muehlencord (joern@muehlencord.de) */ public class BOM { diff --git a/util/src/main/java/de/muehlencord/shared/util/file/BOMStripperInputStream.java b/util/src/main/java/de/muehlencord/shared/util/file/BOMStripperInputStream.java index de6201f..ed9bf02 100644 --- a/util/src/main/java/de/muehlencord/shared/util/file/BOMStripperInputStream.java +++ b/util/src/main/java/de/muehlencord/shared/util/file/BOMStripperInputStream.java @@ -22,7 +22,7 @@ import java.io.PushbackInputStream; /** * Stream which removes the leading BOM from an input stream * - * @author joern.muehlencord + * @author Joern Muehlencord (joern@muehlencord.de) */ public class BOMStripperInputStream extends PushbackInputStream { diff --git a/util/src/test/java/de/muehlencord/shared/util/DefaultTest.java b/util/src/test/java/de/muehlencord/shared/util/DefaultTest.java index 6748f6a..9388d5e 100644 --- a/util/src/test/java/de/muehlencord/shared/util/DefaultTest.java +++ b/util/src/test/java/de/muehlencord/shared/util/DefaultTest.java @@ -1,19 +1,17 @@ /* - * Copyright (C) 2019 Joern Muehlencord (joern@muehlencord.de) + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * http://www.apache.org/licenses/LICENSE-2.0 * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package de.muehlencord.shared.util; diff --git a/util/src/test/java/de/muehlencord/shared/util/LuhnTest.java b/util/src/test/java/de/muehlencord/shared/util/LuhnTest.java new file mode 100644 index 0000000..37afd94 --- /dev/null +++ b/util/src/test/java/de/muehlencord/shared/util/LuhnTest.java @@ -0,0 +1,61 @@ +/* + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.muehlencord.shared.util; + +import static de.muehlencord.shared.util.Luhn.computeCheckDigit; +import static de.muehlencord.shared.util.Luhn.validateNumber; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; + +/** + * + * @author Joern Muehlencord (joern@muehlencord.de) + */ +public class LuhnTest { + + public LuhnTest() { + } + + @Test + public void testComputeCheckDigit() { + String testString = "7992739871"; + int checkNumber = computeCheckDigit(testString, false); + assertTrue(checkNumber == 3); + } + + @Test + public void testValidateNumber() { + assertFalse(validateNumber("79927398710")); + assertFalse(validateNumber("79927398711")); + assertFalse(validateNumber("79927398712")); + assertTrue(validateNumber("79927398713")); + assertFalse(validateNumber("79927398714")); + assertFalse(validateNumber("79927398715")); + assertFalse(validateNumber("79927398716")); + assertFalse(validateNumber("79927398717")); + assertFalse(validateNumber("79927398718")); + assertFalse(validateNumber("79927398719")); + } + +} + +/** + * History: + * + * $$Log$$ + * + */ diff --git a/util/src/test/java/de/muehlencord/shared/util/OSUtilTest.java b/util/src/test/java/de/muehlencord/shared/util/OSUtilTest.java index e5f3f36..47d9256 100644 --- a/util/src/test/java/de/muehlencord/shared/util/OSUtilTest.java +++ b/util/src/test/java/de/muehlencord/shared/util/OSUtilTest.java @@ -1,19 +1,17 @@ /* - * Copyright (C) 2019 Joern Muehlencord (joern@muehlencord.de) + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * http://www.apache.org/licenses/LICENSE-2.0 * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package de.muehlencord.shared.util; diff --git a/util/src/test/java/de/muehlencord/shared/util/PasswordUtilTest.java b/util/src/test/java/de/muehlencord/shared/util/PasswordUtilTest.java new file mode 100644 index 0000000..e2d33bc --- /dev/null +++ b/util/src/test/java/de/muehlencord/shared/util/PasswordUtilTest.java @@ -0,0 +1,59 @@ +/* + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package de.muehlencord.shared.util; + +import java.security.SecureRandom; +import org.bouncycastle.util.encoders.Base64; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +/** + * + * @author Joern Muehlencord (joern@muehlencord.de) + */ +public class PasswordUtilTest { + + private static SecureRandom secureRandom; + private static String systemSalt64Coded; + private static byte[] systemSaltBytes; + + @BeforeAll + public static void init() { + secureRandom = new SecureRandom(); + + systemSaltBytes = new byte[32]; + secureRandom.nextBytes (systemSaltBytes); + systemSalt64Coded = new String(Base64.encode (systemSaltBytes)); + } + + + @Test + public void testGetHash() { + PasswordUtil pwUtil = new PasswordUtil(systemSalt64Coded); + + String password1 = pwUtil.getHash("password"); + String password2 = pwUtil.getHash("password"); + + assertFalse (password1.equals(password2)); + assertTrue (pwUtil.matches ("password", password1)); + assertFalse (pwUtil.matches ("wrongpassword", password1)); + + + } + +} diff --git a/util/src/test/java/de/muehlencord/shared/util/StringEncodingExceptionTest.java b/util/src/test/java/de/muehlencord/shared/util/StringEncodingExceptionTest.java index bee1cff..3f73dd5 100644 --- a/util/src/test/java/de/muehlencord/shared/util/StringEncodingExceptionTest.java +++ b/util/src/test/java/de/muehlencord/shared/util/StringEncodingExceptionTest.java @@ -1,19 +1,17 @@ /* - * Copyright (C) 2019 Joern Muehlencord (joern@muehlencord.de) + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * http://www.apache.org/licenses/LICENSE-2.0 * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package de.muehlencord.shared.util; diff --git a/util/src/test/java/de/muehlencord/shared/util/StringUtilTest.java b/util/src/test/java/de/muehlencord/shared/util/StringUtilTest.java index a8e602f..a154ef2 100644 --- a/util/src/test/java/de/muehlencord/shared/util/StringUtilTest.java +++ b/util/src/test/java/de/muehlencord/shared/util/StringUtilTest.java @@ -1,19 +1,17 @@ /* - * Copyright (C) 2019 Joern Muehlencord (joern@muehlencord.de) + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * http://www.apache.org/licenses/LICENSE-2.0 * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package de.muehlencord.shared.util; diff --git a/util/src/test/java/de/muehlencord/shared/util/file/FileUtilTest.java b/util/src/test/java/de/muehlencord/shared/util/file/FileUtilTest.java index b4f32cb..b679e80 100644 --- a/util/src/test/java/de/muehlencord/shared/util/file/FileUtilTest.java +++ b/util/src/test/java/de/muehlencord/shared/util/file/FileUtilTest.java @@ -1,19 +1,17 @@ /* - * Copyright (C) 2019 Joern Muehlencord (joern@muehlencord.de) + * Copyright 2019 Joern Muehlencord (joern@muehlencord.de). * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * http://www.apache.org/licenses/LICENSE-2.0 * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package de.muehlencord.shared.util.file;