001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.codec.digest; 018 019 import static org.junit.Assert.assertEquals; 020 import static org.junit.Assert.assertNotNull; 021 import static org.junit.Assert.assertNotSame; 022 import static org.junit.Assert.assertTrue; 023 024 import org.apache.commons.codec.Charsets; 025 import org.junit.Test; 026 027 public class UnixCryptTest { 028 029 @Test 030 public void testCtor() { 031 assertNotNull(new UnixCrypt()); 032 } 033 034 @Test 035 public void testUnixCryptStrings() { 036 // trivial test 037 assertEquals("xxWAum7tHdIUw", Crypt.crypt("secret", "xx")); 038 // empty data 039 assertEquals("12UFlHxel6uMM", Crypt.crypt("", "12")); 040 // salt gets cut at maximum length 041 assertEquals("12FJgqDtVOg7Q", Crypt.crypt("secret", "12")); 042 assertEquals("12FJgqDtVOg7Q", Crypt.crypt("secret", "12345678")); 043 } 044 045 @Test 046 public void testUnixCryptBytes() { 047 // An empty Bytearray equals an empty String 048 assertEquals("12UFlHxel6uMM", Crypt.crypt(new byte[0], "12")); 049 // UTF-8 stores \u00e4 "a with diaeresis" as two bytes 0xc3 0xa4. 050 assertEquals("./287bds2PjVw", Crypt.crypt("t\u00e4st", "./")); 051 // ISO-8859-1 stores "a with diaeresis" as single byte 0xe4. 052 assertEquals("./bLIFNqo9XKQ", Crypt.crypt("t\u00e4st".getBytes(Charsets.ISO_8859_1), "./")); 053 assertEquals("./bLIFNqo9XKQ", Crypt.crypt(new byte[]{(byte) 0x74, (byte) 0xe4, (byte) 0x73, (byte) 0x74}, "./")); 054 } 055 056 /** 057 * Some salts are invalid for crypt(3) but not for unixCrypt(). 058 */ 059 @Test 060 public void testUnixCryptExplicitCall() { 061 // A call to crypt() with an empty salt would result in a "$6$" hash. 062 // Using unixCrypt() explicitly results in a random salt. 063 assertTrue(UnixCrypt.crypt("secret".getBytes()).matches("^[a-zA-Z0-9./]{13}$")); 064 assertTrue(UnixCrypt.crypt("secret".getBytes(), null).matches("^[a-zA-Z0-9./]{13}$")); 065 } 066 067 /** 068 * Single character salts are illegal! 069 * E.g. with glibc 2.13, crypt("secret", "x") = "xxZREZpkHZpkI" but 070 * crypt("secret", "xx") = "xxWAum7tHdIUw" which makes it unverifyable. 071 */ 072 @Test(expected = IllegalArgumentException.class) 073 public void testUnixCryptWithHalfSalt() { 074 UnixCrypt.crypt("secret", "x"); 075 } 076 077 /** 078 * Unimplemented "$foo$" salt prefixes would be threated as UnixCrypt salt. 079 */ 080 @Test(expected = IllegalArgumentException.class) 081 public void testUnicCryptInvalidSalt() { 082 UnixCrypt.crypt("secret", "$a"); 083 } 084 085 @Test(expected = NullPointerException.class) 086 public void testUnixCryptNullData() { 087 UnixCrypt.crypt((byte[]) null); 088 } 089 090 @Test(expected = IllegalArgumentException.class) 091 public void testUnixCryptWithEmptySalt() { 092 UnixCrypt.crypt("secret", ""); 093 } 094 095 @Test 096 public void testUnixCryptWithoutSalt() { 097 String hash = UnixCrypt.crypt("foo"); 098 assertTrue(hash.matches("^[a-zA-Z0-9./]{13}$")); 099 String hash2 = UnixCrypt.crypt("foo"); 100 assertNotSame(hash, hash2); 101 } 102 }