Skip to content

Commit 605cd71

Browse files
committed
refactor PKCS5.pbkdf2_hmac_sha1 to use BC APIs
thus less dependent on provider internals (fixes jruby/jruby#3025)
1 parent 051964d commit 605cd71

File tree

2 files changed

+22
-22
lines changed

2 files changed

+22
-22
lines changed

src/main/java/org/jruby/ext/openssl/PKCS5.java

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* The MIT License
33
*
4-
* Copyright 2014 Karol Bucek.
4+
* Copyright 2014-2015 Karol Bucek.
55
*
66
* Permission is hereby granted, free of charge, to any person obtaining a copy
77
* of this software and associated documentation files (the "Software"), to deal
@@ -25,11 +25,12 @@
2525

2626
import java.security.InvalidKeyException;
2727
import java.security.NoSuchAlgorithmException;
28-
import java.security.spec.InvalidKeySpecException;
2928
import javax.crypto.Mac;
30-
import javax.crypto.SecretKey;
31-
import javax.crypto.spec.PBEKeySpec;
32-
import javax.crypto.spec.SecretKeySpec;
29+
30+
import org.bouncycastle.crypto.CipherParameters;
31+
import org.bouncycastle.crypto.PBEParametersGenerator;
32+
import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
33+
import org.bouncycastle.crypto.params.KeyParameter;
3334

3435
import org.jruby.Ruby;
3536
import org.jruby.RubyModule;
@@ -54,12 +55,13 @@ public static void createPKCS5(final Ruby runtime, final RubyModule ossl) {
5455
// def pbkdf2_hmac_sha1(pass, salt, iter, keylen)
5556
@JRubyMethod(meta = true, required = 4)
5657
public static IRubyObject pbkdf2_hmac_sha1(final IRubyObject self, final IRubyObject[] args) {
58+
//final byte[] pass = args[0].asString().getBytes();
5759
final char[] pass = args[0].asString().toString().toCharArray();
5860
final byte[] salt = args[1].asString().getBytes();
5961
final int iter = (int) args[2].convertToInteger().getLongValue();
60-
final int keylen = (int) args[3].convertToInteger().getLongValue(); // e.g. 64
62+
final int keySize = (int) args[3].convertToInteger().getLongValue(); // e.g. 64
6163

62-
return generatePBEKey(self.getRuntime(), pass, salt, iter, keylen, "PBKDF2WithHmacSHA1");
64+
return generatePBEKey(self.getRuntime(), pass, salt, iter, keySize);
6365
}
6466

6567
// def pbkdf2_hmac_sha1(pass, salt, iter, keylen, digest)
@@ -85,7 +87,7 @@ public static IRubyObject pbkdf2_hmac(final IRubyObject self, final IRubyObject[
8587
final Ruby runtime = self.getRuntime();
8688
try {
8789
final Mac mac = SecurityHelper.getMac( macAlg );
88-
mac.init( new SecretKeySpec( pass, macAlg ) );
90+
mac.init( new SimpleSecretKey(macAlg, pass) );
8991
final byte[] key = deriveKey(mac, salt, iter, keylen);
9092
return StringHelper.newString(runtime, key);
9193
}
@@ -106,20 +108,11 @@ private static String mapDigestName(final String name) {
106108
}
107109

108110
private static RubyString generatePBEKey(final Ruby runtime,
109-
final char[] pass, final byte[] salt, final int iter, final int keylen,
110-
final String alg) {
111-
112-
final PBEKeySpec keySpec = new PBEKeySpec(pass, salt, iter, keylen * 8);
113-
try {
114-
SecretKey key = SecurityHelper.getSecretKeyFactory(alg).generateSecret(keySpec);
115-
return StringHelper.newString(runtime, key.getEncoded());
116-
}
117-
catch (NoSuchAlgorithmException ex) {
118-
throw Utils.newRuntimeError(runtime, ex); // should no happen
119-
}
120-
catch (InvalidKeySpecException ex) {
121-
throw Utils.newRuntimeError(runtime, ex); // TODO
122-
}
111+
final char[] pass, final byte[] salt, final int iter, final int keySize) {
112+
PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();
113+
generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(pass), salt, iter);
114+
CipherParameters params = generator.generateDerivedParameters(keySize * 8);
115+
return StringHelper.newString(runtime, ((KeyParameter) params).getKey());
123116
}
124117

125118
// http://stackoverflow.com/questions/9147463/java-pbkdf2-with-hmacsha256-as-the-prf

src/test/ruby/pkcs5/test_pbkdf2.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ def test_pbkdf2_hmac_sha1
1313
assert_equal expected, OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, salt, iter, keylen)
1414
end
1515

16+
def test_pbkdf2_hmac_sha1_with_empty_salt
17+
pass = ' '
18+
expected = "\x81\e\xE9F\xD8op\xA6\x9D\xF4=\tX\x13\x82D\xF7\xF3\x7F\xC8aFR+"
19+
expected.force_encoding('ASCII-8BIT') if ''.respond_to?(:force_encoding)
20+
assert_equal expected, OpenSSL::PKCS5.pbkdf2_hmac_sha1(pass, '', 16, 24)
21+
end
22+
1623
def test_pbkdf2_hmac
1724
pass = 'SecreT2'
1825
salt = '0123456789001234567890'

0 commit comments

Comments
 (0)