001// -------------------------------------------------------------------------------- 002// Copyright 2002-2026 Echo Three, LLC 003// 004// Licensed under the Apache License, Version 2.0 (the "License"); 005// you may not use this file except in compliance with the License. 006// You may obtain a copy of the License at 007// 008// http://www.apache.org/licenses/LICENSE-2.0 009// 010// Unless required by applicable law or agreed to in writing, software 011// distributed under the License is distributed on an "AS IS" BASIS, 012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013// See the License for the specific language governing permissions and 014// limitations under the License. 015// -------------------------------------------------------------------------------- 016 017package com.echothree.util.server.persistence; 018 019import com.echothree.util.common.persistence.BaseKey; 020import com.google.common.io.BaseEncoding; 021import java.nio.charset.StandardCharsets; 022import java.security.MessageDigest; 023import java.security.NoSuchAlgorithmException; 024import javax.enterprise.context.ApplicationScoped; 025import javax.inject.Inject; 026 027@ApplicationScoped 028public class Sha1Utils 029 implements ShaUtils { 030 031 private static final String SHA_1_ALGORITHM = "SHA-1"; 032 033 @Inject 034 RandomUtils randomUtils; 035 036 protected Sha1Utils() { 037 super(); 038 } 039 040 @Override 041 public String generateSalt() { 042 var salt = new byte[8]; 043 044 randomUtils.getRandom().nextBytes(salt); 045 046 return BaseEncoding.base64().encode(salt); 047 } 048 049 @Override 050 public String encode(String salt, String password) { 051 byte[] input; 052 053 try { 054 var sha1Encoder = MessageDigest.getInstance(SHA_1_ALGORITHM); 055 056 sha1Encoder.reset(); 057 sha1Encoder.update(BaseEncoding.base64().decode(salt)); 058 input = sha1Encoder.digest(password.getBytes(StandardCharsets.UTF_8)); 059 060 for(var i = 0; i < 1000; i++) { 061 sha1Encoder.reset(); 062 input = sha1Encoder.digest(input); 063 } 064 } catch (NoSuchAlgorithmException nsae) { 065 input = null; 066 } 067 068 return input == null ? null : BaseEncoding.base64().encode(input); 069 } 070 071 @Override 072 public String encode(BaseKey baseKey1, BaseKey baseKey2) { 073 byte[] input; 074 075 try { 076 var sha1Encoder = MessageDigest.getInstance("SHA-1"); 077 078 sha1Encoder.reset(); 079 sha1Encoder.update(baseKey1.getKey().getEncoded()); 080 sha1Encoder.update(baseKey1.getIv()); 081 sha1Encoder.update(baseKey2.getKey().getEncoded()); 082 sha1Encoder.update(baseKey2.getIv()); 083 input = sha1Encoder.digest(); 084 } catch (NoSuchAlgorithmException nsae) { 085 input = null; 086 } 087 088 return input == null ? null : BaseEncoding.base64().encode(input); 089 } 090 091 @Override 092 public String hash(byte[] bytes) { 093 byte[] input; 094 095 try { 096 var sha1Encoder = MessageDigest.getInstance("SHA-1"); 097 098 sha1Encoder.reset(); 099 sha1Encoder.update(bytes); 100 input = sha1Encoder.digest(); 101 } catch (NoSuchAlgorithmException nsae) { 102 input = null; 103 } 104 105 return input == null ? null : BaseEncoding.base64().encode(input); 106 } 107 108}