저는 여기에 오래된 Symfony2 기반의 어플리케이션을 가지고 있고 Java에서 Dropwizard로 대체를 개발 중입니다. 이전 DB의 모든 사용자 레코드를 새 Datamodel로 마이그레이션했습니다. 암호에 새 필드를 추가하고 이전 암호와 소금 필드도 가져 왔습니다.symfony2와 같은 해시를 java (SHA-512)와 함께 만듭니다.
이제 잘 알려진 절차를 만들고 싶습니다. 사용자가 로그인하게하고, 새로운 암호 필드에 대해 시도하십시오. 실패 할 경우 마이그레이션 된 암호가 작동하면 새로운 알고리즘으로 일반 텍스트 암호를 인코딩하고 새 암호를 새 암호 필드에 저장합니다. 그래서 사용자가 이전 절차에서 새로운 절차로 암호 해시를 포팅합니다.
소리가 간단하고 정상적으로 정상적으로 작동하지만 Symfony와 PHP가 나를 미치게 만듭니다.
내가 붙어있는 곳은 심포니가하는 것처럼 자바로 같은 해쉬를 만드는 것이다.
MessageDigestPasswordEncoder :
public function encodePassword($raw, $salt) {
if ($this->isPasswordTooLong($raw)) {
throw new BadCredentialsException('Invalid password.');
}
if (!in_array($this->algorithm, hash_algos(), true)) {
throw new \LogicException(sprintf('The algorithm "%s" is not supported.', $this->algorithm));
}
$salted = $this->mergePasswordAndSalt($raw, $salt);
$digest = hash($this->algorithm, $salted, true);
// "stretch" hash
for ($i = 1; $i < $this->iterations; ++$i) {
$digest = hash($this->algorithm, $digest.$salted, true);
}
return $this->encodeHashAsBase64 ? base64_encode($digest) : bin2hex($digest);
}
그리고 BasePasswordEncoder :
) 중요한 방법은, 오래된 응용 프로그램은 "SHA512"base64 인코딩 및 5000 반복, 모든 기본값으로 MessageDigestPasswordEncoder를 사용
protected function mergePasswordAndSalt($password, $salt) {
if (empty($salt)) {
return $password;
}
if (false !== strrpos($salt, '{') || false !== strrpos($salt, '}')) {
throw new \InvalidArgumentException('Cannot use { or } in salt.');
}
return $password.'{'.$salt.'}';
}
똑바로 보이지만 나는 그걸로 붙어 있습니다. 내가 이것을 읽으면서 그것을 수행합니다 변수
- 가 소금과 일반 텍스트 암호를 병합: 5K 시간과는
- 인코딩을 소화로 그래서 여기
자바에서 내 시도하다 64 기수로 소화 재탕하는 병합 된 텍스트 암호와 연결 Digest를 사용
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public void legacyEncryption(String salt, String clearPassword) throws UnsupportedEncodingException, NoSuchAlgorithmException {
// Get digester instance for algorithm "SHA-512" using BounceCastle
MessageDigest digester = MessageDigest.getInstance("SHA-512", new BouncyCastleProvider());
// Create salted password string
String mergedPasswordAndSalt = clearPassword + "{" + salt + "}";
// First time hash the input string by using UTF-8 encoded bytes.
byte[] hash = digester.digest(mergedPasswordAndSalt.getBytes("UTF-8"));
// Loop 5k times
for (int i = 0; i < 5000; i++) {
// Concatenate the hash bytes with the clearPassword bytes and rehash
hash = digester.digest(ArrayUtils.addAll(hash, mergedPasswordAndSalt.getBytes("UTF-8")));
}
// Log the resulting hash as base64 String
logger.info("Legace password digest: salt=" + salt + " hash=" + Base64.getEncoder().encodeToString(hash));
}
아무도 문제가 보이지 않습니까? PHP : binary.binary 및 JAVA : 및 addAll (바이트 [] 바이트 []) 미리
덕분
나는 소리를 좋게 만들고 감각을 만듭니다.) 나는 내일 시도 할 것입니다.이제 막 작성 완료 –
PHP 코드에서 for 루프에서'$ this-> iterations'가'5,000'이고'$ i'가'1'로 초기화되면 for 루프는'4,999' 번 반복합니다. '5,000'번이 아니다. 첫 번째 라운드가 PHP 코드의 루프 바깥에서 이루어 지므로 PHP와 Java 코드는 모두 '5,000 번'반복해야합니다. –
당신이 맞습니다, PHP 코드는 반복 5000 (4999 + 1) 번 않습니다. 그러나 Java 코드는 루프 외부에서 초기 라운드가 있으므로 5001 회 (5000 + 1) 반복합니다. 내 대답에 두 언어를 혼동했다. 미안하다. 나는 그것을 고쳐 줄 것이다. 나는 아직도 그것이 문제의 뿌리라고 생각한다. –