Commit 214f0848 by Kim Jinsung

#38039 パスワードソルト付加対応

parent c2abc033
...@@ -14,24 +14,24 @@ import java.util.Observer; ...@@ -14,24 +14,24 @@ import java.util.Observer;
import jp.agentec.abook.abv.bl.acms.client.json.AcmsBooleanResultJSON; import jp.agentec.abook.abv.bl.acms.client.json.AcmsBooleanResultJSON;
import jp.agentec.abook.abv.bl.acms.client.json.AcmsCommonJSON; import jp.agentec.abook.abv.bl.acms.client.json.AcmsCommonJSON;
import jp.agentec.abook.abv.bl.acms.client.json.AcmsMessageJSON; import jp.agentec.abook.abv.bl.acms.client.json.AcmsMessageJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ApertureMasterDataJSON;
import jp.agentec.abook.abv.bl.acms.client.json.AppLatestVersionJSON; import jp.agentec.abook.abv.bl.acms.client.json.AppLatestVersionJSON;
import jp.agentec.abook.abv.bl.acms.client.json.AuthLevelJSON; import jp.agentec.abook.abv.bl.acms.client.json.AuthLevelJSON;
import jp.agentec.abook.abv.bl.acms.client.json.CategoriesJSON; import jp.agentec.abook.abv.bl.acms.client.json.CategoriesJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ContentCheckDeliverableJSON; import jp.agentec.abook.abv.bl.acms.client.json.ContentCheckDeliverableJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ContentVersionsJSON; import jp.agentec.abook.abv.bl.acms.client.json.ContentVersionsJSON;
import jp.agentec.abook.abv.bl.acms.client.json.FixPushMessageJSON;
import jp.agentec.abook.abv.bl.acms.client.json.GroupsJSON; import jp.agentec.abook.abv.bl.acms.client.json.GroupsJSON;
import jp.agentec.abook.abv.bl.acms.client.json.LogSendFlagJSON; import jp.agentec.abook.abv.bl.acms.client.json.LogSendFlagJSON;
import jp.agentec.abook.abv.bl.acms.client.json.NewAppStoreLoginJSON; import jp.agentec.abook.abv.bl.acms.client.json.NewAppStoreLoginJSON;
import jp.agentec.abook.abv.bl.acms.client.json.OperationDataJSON;
import jp.agentec.abook.abv.bl.acms.client.json.OperationGroupMasterJSON; import jp.agentec.abook.abv.bl.acms.client.json.OperationGroupMasterJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ApertureMasterDataJSON; import jp.agentec.abook.abv.bl.acms.client.json.OperationListJSON;
import jp.agentec.abook.abv.bl.acms.client.json.RequirePasswordChangeJSON; import jp.agentec.abook.abv.bl.acms.client.json.RequirePasswordChangeJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ResultJSON; import jp.agentec.abook.abv.bl.acms.client.json.ResultJSON;
import jp.agentec.abook.abv.bl.acms.client.json.SceneEntryJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ServerTimeZoneJSON; import jp.agentec.abook.abv.bl.acms.client.json.ServerTimeZoneJSON;
import jp.agentec.abook.abv.bl.acms.client.json.ServiceOptionsJSON; import jp.agentec.abook.abv.bl.acms.client.json.ServiceOptionsJSON;
import jp.agentec.abook.abv.bl.acms.client.json.FixPushMessageJSON;
import jp.agentec.abook.abv.bl.acms.client.json.OperationDataJSON;
import jp.agentec.abook.abv.bl.acms.client.json.OperationListJSON;
import jp.agentec.abook.abv.bl.acms.client.json.SceneEntryJSON;
import jp.agentec.abook.abv.bl.acms.client.json.WorkerGroupJSON; import jp.agentec.abook.abv.bl.acms.client.json.WorkerGroupJSON;
import jp.agentec.abook.abv.bl.acms.client.parameters.AbstractAcmsLoginParameters; import jp.agentec.abook.abv.bl.acms.client.parameters.AbstractAcmsLoginParameters;
import jp.agentec.abook.abv.bl.acms.client.parameters.AcmsContentParameters; import jp.agentec.abook.abv.bl.acms.client.parameters.AcmsContentParameters;
...@@ -68,7 +68,6 @@ import jp.agentec.abook.abv.bl.common.exception.JSONValidationException; ...@@ -68,7 +68,6 @@ import jp.agentec.abook.abv.bl.common.exception.JSONValidationException;
import jp.agentec.abook.abv.bl.common.exception.NetworkDisconnectedException; import jp.agentec.abook.abv.bl.common.exception.NetworkDisconnectedException;
import jp.agentec.abook.abv.bl.common.log.Logger; import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.common.nw.NetworkAdapter; import jp.agentec.abook.abv.bl.common.nw.NetworkAdapter;
import jp.agentec.abook.abv.bl.common.util.SecurityUtil;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao; import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.MemberInfoDao; import jp.agentec.abook.abv.bl.data.dao.MemberInfoDao;
import jp.agentec.abook.abv.bl.dto.CategoryDto; import jp.agentec.abook.abv.bl.dto.CategoryDto;
...@@ -200,9 +199,8 @@ public class AcmsClient implements AcmsClientResponseListener { ...@@ -200,9 +199,8 @@ public class AcmsClient implements AcmsClientResponseListener {
if (json.result) { if (json.result) {
dto.invalidPasswordCount = (short) 0; dto.invalidPasswordCount = (short) 0;
dto.lastLoginDate = json.presentTime; dto.lastLoginDate = json.presentTime;
//パスワードは暗号化して保存する。
// パスワードは暗号化して保存する。 dto.password = param.getPassword();
dto.password = SecurityUtil.encryptPassword(param.getPassword(), ABVEnvironment.LoginPasswordAESKey);
} else { } else {
if (json.requirePasswordChange == RequirePasswordChangeCode.FirstTime if (json.requirePasswordChange == RequirePasswordChangeCode.FirstTime
|| json.requirePasswordChange == RequirePasswordChangeCode.Required) { || json.requirePasswordChange == RequirePasswordChangeCode.Required) {
......
...@@ -152,5 +152,11 @@ public interface ServiceOption { ...@@ -152,5 +152,11 @@ public interface ServiceOption {
* 作業種別:N(通常)、Y(作業種別毎に絞り込み可能なボタン・画面表示) * 作業種別:N(通常)、Y(作業種別毎に絞り込み可能なボタン・画面表示)
*/ */
int OperationGroupMaster = 175; int OperationGroupMaster = 175;
/**
* ユーザパスワードソルト付加
* 利用しない:N(通常)、利用する:Y
*/
int AddUserPasswordSalt = 181;
} }
} }
\ No newline at end of file
package jp.agentec.abook.abv.bl.common.util; package jp.agentec.abook.abv.bl.common.util;
import org.apache.commons.codec.binary.Base64;
import java.security.InvalidKeyException; import java.security.InvalidKeyException;
import java.security.Key; import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException; import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException; import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException; import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64; import jp.agentec.abook.abv.bl.common.ABVEnvironment;
import jp.agentec.abook.abv.bl.common.exception.ABVRuntimeException; import jp.agentec.abook.abv.bl.common.exception.ABVRuntimeException;
import jp.agentec.abook.abv.bl.data.ABVDataCache;
import jp.agentec.adf.security.cryptography.AES; import jp.agentec.adf.security.cryptography.AES;
import jp.agentec.adf.security.cryptography.MD5; import jp.agentec.adf.security.cryptography.MD5;
import jp.agentec.adf.util.StringUtil; import jp.agentec.adf.util.StringUtil;
...@@ -249,4 +252,52 @@ public class SecurityUtil { ...@@ -249,4 +252,52 @@ public class SecurityUtil {
} }
} }
/**
* @version 1.2.200
* サービスオプション「ユーザパスワードソルト付加」がtrueの場合、
* パスワードとログインIDをソルトしてから結合し、MD5値を返却します
* falseの場合、既存暗号化パスワード返す。
*
* @param password 通常パスワード
* @param loginId 通常ログインID
* @return MD5化されたパスワード(password+salt)
*/
public static String getEncriptPassword(String password, String loginId) {
//新しいパスワード暗号化
if (ABVDataCache.getInstance().serviceOption.isAddUserPasswordSalt()) {
String salt = getHashedSalt(loginId);
try {
return MD5.getMd5Hash(loginId + salt);
} catch (NoSuchAlgorithmException e) {
throw new ABVRuntimeException(e);
}
}
//既存パスワード暗号化
return encryptPassword(password, ABVEnvironment.LoginPasswordAESKey);
}
/**
* ユーザID(ソルト)をハッシュ化して返却します
* ※ハッシュアルゴリズムはSHA-256を使用
*
* @param salt ソルト(ユーザID)
* @return ハッシュ化された文字列(大文字)
*
*/
private static String getHashedSalt(String salt) {
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
messageDigest.update(salt.getBytes());
byte[] encryptSalt = messageDigest.digest();
StringBuilder sb = new StringBuilder(64);
for (byte b : encryptSalt) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString().toUpperCase();
}
} }
...@@ -337,6 +337,15 @@ public class ABVDataCache { ...@@ -337,6 +337,15 @@ public class ABVDataCache {
} }
/** /**
* @version 1.2.200
* サービスオプション(ユーザパスワードソルト付加)返す
* @return true:利用する, false:利用しない
*/
public boolean isAddUserPasswordSalt() {
return isServiceOptionEnable(ServiceOptionId.AddUserPasswordSalt);
}
/**
* 作業種別のサービスオプション情報取得 * 作業種別のサービスオプション情報取得
* @return * @return
*/ */
......
...@@ -294,7 +294,7 @@ public class UserAuthenticateLogic extends AbstractLogic { ...@@ -294,7 +294,7 @@ public class UserAuthenticateLogic extends AbstractLogic {
if (StringUtil.isNullOrWhiteSpace(password)) { if (StringUtil.isNullOrWhiteSpace(password)) {
throw new IllegalArgumentException("argument oldPassword and newPassword not allowed null or white space. "); throw new IllegalArgumentException("argument oldPassword and newPassword not allowed null or white space. ");
} }
String encryptedPassword = SecurityUtil.encryptPassword(password, ABVEnvironment.LoginPasswordAESKey); String encryptedPassword = SecurityUtil.getEncriptPassword(password, dto.loginId);
result = dto.password.equals(encryptedPassword); result = dto.password.equals(encryptedPassword);
} else { } else {
throw new ABVRuntimeException(ABVExceptionCode.C_E_SECURITY_1004); throw new ABVRuntimeException(ABVExceptionCode.C_E_SECURITY_1004);
...@@ -304,7 +304,7 @@ public class UserAuthenticateLogic extends AbstractLogic { ...@@ -304,7 +304,7 @@ public class UserAuthenticateLogic extends AbstractLogic {
} }
public boolean checkPassword(MemberInfoDto dto, String password) { public boolean checkPassword(MemberInfoDto dto, String password) {
String encryptedPassword = SecurityUtil.encryptPassword(password, ABVEnvironment.LoginPasswordAESKey); String encryptedPassword = SecurityUtil.getEncriptPassword(password, dto.loginId);
return dto.password.equals(encryptedPassword); return dto.password.equals(encryptedPassword);
} }
...@@ -327,7 +327,7 @@ public class UserAuthenticateLogic extends AbstractLogic { ...@@ -327,7 +327,7 @@ public class UserAuthenticateLogic extends AbstractLogic {
throw new IllegalArgumentException("argument oldPassword and newPassword not allowed null or white space. "); throw new IllegalArgumentException("argument oldPassword and newPassword not allowed null or white space. ");
} }
String oldEncryptedPassword = SecurityUtil.encryptPassword(oldPassword, ABVEnvironment.LoginPasswordAESKey); String oldEncryptedPassword = SecurityUtil.getEncriptPassword(oldPassword, dto.loginId);
String newEncryptedPassword; String newEncryptedPassword;
if (!dto.password.equals(oldEncryptedPassword)) { if (!dto.password.equals(oldEncryptedPassword)) {
...@@ -340,7 +340,7 @@ public class UserAuthenticateLogic extends AbstractLogic { ...@@ -340,7 +340,7 @@ public class UserAuthenticateLogic extends AbstractLogic {
result = AcmsClient.getInstance(cache.getUrlPath(), networkAdapter).passwordChange(param); result = AcmsClient.getInstance(cache.getUrlPath(), networkAdapter).passwordChange(param);
if (result) { if (result) {
newEncryptedPassword = SecurityUtil.encryptPassword(newPassword, ABVEnvironment.LoginPasswordAESKey); newEncryptedPassword = SecurityUtil.getEncriptPassword(newPassword, dto.loginId);
dto.password = newEncryptedPassword; dto.password = newEncryptedPassword;
dto.loginStatus = LoginStatus.LoggedIn.statusCode(); dto.loginStatus = LoginStatus.LoggedIn.statusCode();
......
...@@ -15,6 +15,7 @@ import jp.agentec.abook.abv.bl.common.exception.ABVExceptionCode; ...@@ -15,6 +15,7 @@ import jp.agentec.abook.abv.bl.common.exception.ABVExceptionCode;
import jp.agentec.abook.abv.bl.common.exception.AcmsException; import jp.agentec.abook.abv.bl.common.exception.AcmsException;
import jp.agentec.abook.abv.bl.common.exception.NetworkDisconnectedException; import jp.agentec.abook.abv.bl.common.exception.NetworkDisconnectedException;
import jp.agentec.abook.abv.bl.common.log.Logger; import jp.agentec.abook.abv.bl.common.log.Logger;
import jp.agentec.abook.abv.bl.common.util.SecurityUtil;
import jp.agentec.abook.abv.bl.data.dao.AbstractDao; import jp.agentec.abook.abv.bl.data.dao.AbstractDao;
import jp.agentec.abook.abv.bl.data.dao.AcmsDao; import jp.agentec.abook.abv.bl.data.dao.AcmsDao;
import jp.agentec.abook.abv.bl.data.dao.MemberInfoDao; import jp.agentec.abook.abv.bl.data.dao.MemberInfoDao;
...@@ -516,6 +517,7 @@ public class LoginActivity extends ABVLoginActivity { ...@@ -516,6 +517,7 @@ public class LoginActivity extends ABVLoginActivity {
// パスワード変更の状況に合わせてログインステータスの書き換え // パスワード変更の状況に合わせてログインステータスの書き換え
dto.loginStatus = userAuthenticateLogic.convertLoginStatusFromChangePasswordType(changePasswordType); dto.loginStatus = userAuthenticateLogic.convertLoginStatusFromChangePasswordType(changePasswordType);
dto.password = SecurityUtil.getEncriptPassword(dto.password, dto.loginId);
userAuthenticateLogic.saveMemberInfo(dto, mUrlPath); userAuthenticateLogic.saveMemberInfo(dto, mUrlPath);
if (changePasswordType == RequirePasswordChangeType.NONE) { if (changePasswordType == RequirePasswordChangeType.NONE) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment