1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.wss4j.common.derivedKey;
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 import javax.crypto.Mac;
43 import javax.crypto.spec.SecretKeySpec;
44 import javax.security.auth.DestroyFailedException;
45
46 import org.apache.wss4j.common.ext.WSSecurityException;
47
48 import java.security.InvalidKeyException;
49 import java.security.NoSuchAlgorithmException;
50
51 public class P_SHA1 implements DerivationAlgorithm {
52
53 private static final org.slf4j.Logger LOG =
54 org.slf4j.LoggerFactory.getLogger(P_SHA1.class);
55
56 @Override
57 public byte[] createKey(byte[] secret, byte[] seed, int offset, long length)
58 throws WSSecurityException {
59
60 try {
61 Mac mac = Mac.getInstance("HmacSHA1");
62
63 byte[] tempBytes = pHash(secret, seed, mac, offset + (int) length);
64
65 byte[] key = new byte[(int) length];
66
67 System.arraycopy(tempBytes, offset, key, 0, key.length);
68
69 return key;
70 } catch (NoSuchAlgorithmException | InvalidKeyException e) {
71 throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, e, "errorInKeyDerivation");
72 }
73 }
74
75
76
77
78
79
80
81
82
83
84
85 private static byte[] pHash(byte[] secret, byte[] seed, Mac mac, int required)
86 throws InvalidKeyException {
87
88 byte[] out = new byte[required];
89 int offset = 0, tocpy;
90 byte[] a = seed;
91 byte[] tmp;
92
93 SecretKeySpec key = new SecretKeySpec(secret, "HMACSHA1");
94 mac.init(key);
95
96 int bytesRequired = required;
97 while (bytesRequired > 0) {
98 mac.update(a);
99 a = mac.doFinal();
100 mac.update(a);
101 mac.update(seed);
102 tmp = mac.doFinal();
103 tocpy = Math.min(bytesRequired, tmp.length);
104 System.arraycopy(tmp, 0, out, offset, tocpy);
105 offset += tocpy;
106 bytesRequired -= tocpy;
107 }
108
109 try {
110 key.destroy();
111 } catch (DestroyFailedException e) {
112 LOG.debug("Error destroying key: {}", e.getMessage());
113 }
114 return out;
115 }
116 }