Repository: cxf Updated Branches: refs/heads/master 7683d0551 -> 22dbf10ed
[CXF-5311] Quick prototyping of JwsOutputStream, refactorings will follow Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/22dbf10e Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/22dbf10e Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/22dbf10e Branch: refs/heads/master Commit: 22dbf10ed281f3ec94b159829e21333f4afc0bf9 Parents: 7683d05 Author: Sergey Beryozkin <[email protected]> Authored: Thu Jul 10 13:41:56 2014 +0100 Committer: Sergey Beryozkin <[email protected]> Committed: Thu Jul 10 13:41:56 2014 +0100 ---------------------------------------------------------------------- .../security/oauth2/jwe/JweCompactProducer.java | 7 +- .../rs/security/oauth2/jwe/JweOutputStream.java | 2 +- .../jws/AbstractJwsSignatureProvider.java | 33 ++++++- .../oauth2/jws/HmacJwsSignatureProvider.java | 21 ++++- .../rs/security/oauth2/jws/JwsOutputStream.java | 98 ++++++++++++++++++++ .../oauth2/jws/JwsSignatureProvider.java | 5 +- .../oauth2/jws/JwsSignatureProviderWorker.java | 25 +++++ .../jws/PrivateKeyJwsSignatureProvider.java | 33 ++++++- .../oauth2/jwt/jaxrs/JwsWriterInterceptor.java | 33 +++++-- .../oauth2/utils/crypto/CryptoUtils.java | 14 ++- 10 files changed, 250 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactProducer.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactProducer.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactProducer.java index 72d3d84..365a986 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactProducer.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweCompactProducer.java @@ -112,12 +112,13 @@ public class JweCompactProducer { writer = writer == null ? new JwtTokenReaderWriter() : writer; byte[] jsonBytes = writer.headersToJson(headers).getBytes("UTF-8"); Base64UrlUtility.encodeAndStream(jsonBytes, 0, jsonBytes.length, os); - os.write('.'); + byte[] dotBytes = new byte[]{'.'}; + os.write(dotBytes); Base64UrlUtility.encodeAndStream(encryptedContentEncryptionKey, 0, encryptedContentEncryptionKey.length, os); - os.write('.'); + os.write(dotBytes); Base64UrlUtility.encodeAndStream(cipherInitVector, 0, cipherInitVector.length, os); - os.write('.'); + os.write(dotBytes); } public String getJweContent() { http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweOutputStream.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweOutputStream.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweOutputStream.java index ebf80df..91b68b0 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweOutputStream.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwe/JweOutputStream.java @@ -106,7 +106,7 @@ public class JweOutputStream extends FilterOutputStream { ? encryptingCipher.doFinal() : encryptingCipher.doFinal(lastRawDataChunk, 0, lastRawDataChunk.length); encodeAndWrite(finalBytes, 0, finalBytes.length - authTagLengthBits / 8, true); - out.write('.'); + out.write(new byte[]{'.'}); encodeAndWrite(finalBytes, finalBytes.length - authTagLengthBits / 8, authTagLengthBits / 8, true); } catch (Exception ex) { throw new SecurityException(); http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/AbstractJwsSignatureProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/AbstractJwsSignatureProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/AbstractJwsSignatureProvider.java index 83563be..dc63a1e 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/AbstractJwsSignatureProvider.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/AbstractJwsSignatureProvider.java @@ -18,27 +18,54 @@ */ package org.apache.cxf.rs.security.oauth2.jws; +import java.io.OutputStream; import java.util.Set; +import org.apache.cxf.common.util.Base64Utility; import org.apache.cxf.rs.security.oauth2.jwt.JwtHeaders; +import org.apache.cxf.rs.security.oauth2.jwt.JwtTokenReaderWriter; public abstract class AbstractJwsSignatureProvider implements JwsSignatureProvider { private Set<String> supportedAlgorithms; private String defaultJwtAlgorithm; - public AbstractJwsSignatureProvider(Set<String> supportedAlgorithms) { + protected AbstractJwsSignatureProvider(Set<String> supportedAlgorithms) { this.supportedAlgorithms = supportedAlgorithms; } @Override - public void prepareHeaders(JwtHeaders headers) { + public JwtHeaders prepareHeaders(JwtHeaders headers) { + if (headers == null) { + headers = new JwtHeaders(); + } String algo = headers.getAlgorithm(); if (algo != null) { checkAlgorithm(algo); } else { headers.setAlgorithm(defaultJwtAlgorithm); } - + return headers; + } + + @Override + public JwsOutputStream createJwsStream(OutputStream os, String contentType) { + JwtHeaders headers = new JwtHeaders(); + if (contentType != null) { + headers.setContentType(contentType); + } + headers = prepareHeaders(headers); + JwsSignatureProviderWorker worker = createJwsSignatureWorker(headers); + try { + byte[] headerBytes = new JwtTokenReaderWriter().headersToJson(headers).getBytes("UTF-8"); + Base64Utility.encodeAndStream(headerBytes, 0, headerBytes.length, os); + os.write(new byte[]{'.'}); + } catch (Exception ex) { + throw new SecurityException(ex); + } + return new JwsOutputStream(os, worker); } + + protected abstract JwsSignatureProviderWorker createJwsSignatureWorker(JwtHeaders headers); + public void setDefaultJwtAlgorithm(String algo) { this.defaultJwtAlgorithm = algo; } http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/HmacJwsSignatureProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/HmacJwsSignatureProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/HmacJwsSignatureProvider.java index ed4c00f..6bb1e0d 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/HmacJwsSignatureProvider.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/HmacJwsSignatureProvider.java @@ -22,6 +22,8 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import javax.crypto.Mac; + import org.apache.cxf.common.util.Base64Exception; import org.apache.cxf.rs.security.oauth2.jwt.Algorithm; import org.apache.cxf.rs.security.oauth2.jwt.JwtHeaders; @@ -50,7 +52,7 @@ public class HmacJwsSignatureProvider extends AbstractJwsSignatureProvider imple @Override public byte[] sign(JwtHeaders headers, String unsignedText) { - checkAlgorithm(headers.getAlgorithm()); + headers = prepareHeaders(headers); return computeMac(headers, unsignedText); } @@ -65,5 +67,22 @@ public class HmacJwsSignatureProvider extends AbstractJwsSignatureProvider imple Algorithm.toJavaName(headers.getAlgorithm()), text); } + @Override + protected JwsSignatureProviderWorker createJwsSignatureWorker(JwtHeaders headers) { + final Mac mac = HmacUtils.getMac(Algorithm.toJavaName(headers.getAlgorithm())); + return new JwsSignatureProviderWorker() { + + @Override + public void update(byte[] src, int off, int len) { + mac.update(src, off, len); + } + + @Override + public byte[] sign() { + return mac.doFinal(); + } + + }; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsOutputStream.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsOutputStream.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsOutputStream.java new file mode 100644 index 0000000..8c7734d --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsOutputStream.java @@ -0,0 +1,98 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.jws; + +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.nio.ByteBuffer; + +import org.apache.cxf.rs.security.oauth2.utils.Base64UrlUtility; + +public class JwsOutputStream extends FilterOutputStream { + private byte[] lastNonEncodedDataChunk; + private boolean flushed; + private JwsSignatureProviderWorker signature; + public JwsOutputStream(OutputStream out, JwsSignatureProviderWorker signature) { + super(out); + this.signature = signature; + } + + @Override + public void write(int value) throws IOException { + byte[] bytes = ByteBuffer.allocate(Integer.SIZE / 8).putInt(value).array(); + write(bytes, 0, bytes.length); + } + + @Override + public void write(byte b[], int off, int len) throws IOException { + try { + signature.update(b, off, len); + } catch (Throwable ex) { + throw new SecurityException(); + } + encodeAndWrite(b, off, len, false); + } + + private void encodeAndWrite(byte[] encryptedChunk, int off, int len, boolean finalWrite) throws IOException { + byte[] theChunk = lastNonEncodedDataChunk; + int lenToEncode = len; + if (theChunk != null) { + theChunk = newArray(theChunk, 0, theChunk.length, encryptedChunk, off, len); + lenToEncode = theChunk.length; + off = 0; + } else { + theChunk = encryptedChunk; + } + int rem = finalWrite ? 0 : lenToEncode % 3; + Base64UrlUtility.encodeAndStream(theChunk, off, lenToEncode - rem, out); + + if (rem > 0) { + lastNonEncodedDataChunk = newArray(theChunk, lenToEncode - rem, rem); + } else { + lastNonEncodedDataChunk = null; + } + } + + @Override + public void flush() throws IOException { + if (flushed) { + return; + } + try { + byte[] finalBytes = signature.sign(); + out.write('.'); + encodeAndWrite(finalBytes, 0, finalBytes.length, true); + } catch (Exception ex) { + throw new SecurityException(); + } + flushed = true; + } + private byte[] newArray(byte[] src, int srcPos, int srcLen) { + byte[] buf = new byte[srcLen]; + System.arraycopy(src, srcPos, buf, 0, srcLen); + return buf; + } + private byte[] newArray(byte[] src, int srcPos, int srcLen, byte[] src2, int srcPos2, int srcLen2) { + byte[] buf = new byte[srcLen + srcLen2]; + System.arraycopy(src, srcPos, buf, 0, srcLen); + System.arraycopy(src2, srcPos2, buf, srcLen, srcLen2); + return buf; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProvider.java index 6fe5e3c..4f97f91 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProvider.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProvider.java @@ -18,9 +18,12 @@ */ package org.apache.cxf.rs.security.oauth2.jws; +import java.io.OutputStream; + import org.apache.cxf.rs.security.oauth2.jwt.JwtHeaders; public interface JwsSignatureProvider { - void prepareHeaders(JwtHeaders headers); + JwtHeaders prepareHeaders(JwtHeaders headers); byte[] sign(JwtHeaders headers, String unsignedText); + JwsOutputStream createJwsStream(OutputStream os, String contentType); } http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProviderWorker.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProviderWorker.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProviderWorker.java new file mode 100644 index 0000000..ca768d5 --- /dev/null +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/JwsSignatureProviderWorker.java @@ -0,0 +1,25 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cxf.rs.security.oauth2.jws; + + +public interface JwsSignatureProviderWorker { + void update(byte[] src, int off, int len); + byte[] sign(); +} http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java index cbfd21e..7d34fac 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jws/PrivateKeyJwsSignatureProvider.java @@ -20,6 +20,8 @@ package org.apache.cxf.rs.security.oauth2.jws; import java.security.PrivateKey; import java.security.SecureRandom; +import java.security.Signature; +import java.security.SignatureException; import java.security.spec.AlgorithmParameterSpec; import java.util.Arrays; import java.util.HashSet; @@ -51,10 +53,9 @@ public class PrivateKeyJwsSignatureProvider extends AbstractJwsSignatureProvider this.signatureSpec = spec; } - @Override public byte[] sign(JwtHeaders headers, String unsignedText) { - checkAlgorithm(headers.getAlgorithm()); + headers = prepareHeaders(headers); try { return CryptoUtils.signData(unsignedText.getBytes("UTF-8"), key, @@ -65,6 +66,34 @@ public class PrivateKeyJwsSignatureProvider extends AbstractJwsSignatureProvider throw new SecurityException(ex); } } + @Override + protected JwsSignatureProviderWorker createJwsSignatureWorker(JwtHeaders headers) { + final Signature s = CryptoUtils.getSignature(key, + Algorithm.toJavaName(headers.getAlgorithm()), + random, + signatureSpec); + return new JwsSignatureProviderWorker() { + + @Override + public void update(byte[] src, int off, int len) { + try { + s.update(src, off, len); + } catch (SignatureException ex) { + throw new SecurityException(); + } + } + + @Override + public byte[] sign() { + try { + return s.sign(); + } catch (SignatureException ex) { + throw new SecurityException(); + } + } + + }; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java index 62c4126..c672e29 100644 --- a/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java +++ b/rt/rs/security/oauth-parent/oauth2-jwt/src/main/java/org/apache/cxf/rs/security/oauth2/jwt/jaxrs/JwsWriterInterceptor.java @@ -30,30 +30,47 @@ import javax.ws.rs.ext.WriterInterceptorContext; import org.apache.cxf.io.CachedOutputStream; import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.rs.security.oauth2.jws.JwsCompactProducer; +import org.apache.cxf.rs.security.oauth2.jws.JwsOutputStream; import org.apache.cxf.rs.security.oauth2.jwt.JwtHeaders; @Priority(Priorities.JWS_WRITE_PRIORITY) public class JwsWriterInterceptor extends AbstractJwsWriterProvider implements WriterInterceptor { private boolean contentTypeRequired = true; + private boolean useJwsOutputStream; @Override public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException, WebApplicationException { OutputStream actualOs = ctx.getOutputStream(); - CachedOutputStream cos = new CachedOutputStream(); - ctx.setOutputStream(cos); - ctx.proceed(); - - JwtHeaders headers = new JwtHeaders(); + String ctString = null; if (contentTypeRequired) { MediaType mt = ctx.getMediaType(); if (mt != null) { - headers.setContentType(JAXRSUtils.mediaTypeToString(mt)); + ctString = JAXRSUtils.mediaTypeToString(mt); + } + } + if (useJwsOutputStream) { + JwsOutputStream cos = getInitializedSigProvider().createJwsStream(actualOs, ctString); + ctx.setOutputStream(cos); + ctx.proceed(); + cos.flush(); + } else { + CachedOutputStream cos = new CachedOutputStream(); + ctx.setOutputStream(cos); + ctx.proceed(); + + JwtHeaders headers = new JwtHeaders(); + if (ctString != null) { + headers.setContentType(ctString); } + JwsCompactProducer p = new JwsCompactProducer(headers, new String(cos.getBytes(), "UTF-8")); + writeJws(p, actualOs); } - JwsCompactProducer p = new JwsCompactProducer(headers, new String(cos.getBytes(), "UTF-8")); - writeJws(p, actualOs); } public void setContentTypeRequired(boolean contentTypeRequired) { this.contentTypeRequired = contentTypeRequired; } + + public void setUseJwsOutputStream(boolean useJwsOutputStream) { + this.useJwsOutputStream = useJwsOutputStream; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/22dbf10e/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java index 76b62aa..1030240 100644 --- a/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java +++ b/rt/rs/security/oauth-parent/oauth2/src/main/java/org/apache/cxf/rs/security/oauth2/utils/crypto/CryptoUtils.java @@ -303,6 +303,17 @@ public final class CryptoUtils { public static byte[] signData(byte[] data, PrivateKey key, String signAlgo, SecureRandom random, AlgorithmParameterSpec params) { try { + Signature s = getSignature(key, signAlgo, random, params); + s.update(data); + return s.sign(); + } catch (Exception ex) { + throw new SecurityException(ex); + } + } + + public static Signature getSignature(PrivateKey key, String signAlgo, SecureRandom random, + AlgorithmParameterSpec params) { + try { Signature s = Signature.getInstance(signAlgo); if (random == null) { s.initSign(key); @@ -312,8 +323,7 @@ public final class CryptoUtils { if (params != null) { s.setParameter(params); } - s.update(data); - return s.sign(); + return s; } catch (Exception ex) { throw new SecurityException(ex); }
