/* * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. * * Copyright (c) 2014, Gluu */ package org.xdi.oxauth.model.crypto.signature; import com.google.common.base.Strings; import org.xdi.oxauth.model.util.Base64Util; import org.xdi.oxauth.model.util.Util; import java.io.UnsupportedEncodingException; import java.security.*; import java.security.spec.InvalidKeySpecException; import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; /** * @author Javier Rojas Blum * @version July 31, 2016 */ public class RSASigner extends AbstractSigner { private RSAPrivateKey rsaPrivateKey; private RSAPublicKey rsaPublicKey; public RSASigner(SignatureAlgorithm signatureAlgorithm, RSAPrivateKey rsaPrivateKey) throws Exception { this(signatureAlgorithm); if (rsaPrivateKey == null) { throw new Exception("Invalid RSA private key"); } this.rsaPrivateKey = rsaPrivateKey; } public RSASigner(SignatureAlgorithm signatureAlgorithm, RSAPublicKey rsaPublicKey) throws Exception { this(signatureAlgorithm); if (rsaPublicKey == null) { throw new Exception("Invalid RSA public key"); } this.rsaPublicKey = rsaPublicKey; } private RSASigner(SignatureAlgorithm signatureAlgorithm) throws Exception { super(signatureAlgorithm); if (signatureAlgorithm == null || !SignatureAlgorithmFamily.RSA.equals(signatureAlgorithm.getFamily())) { throw new Exception("Invalid signature algorithm"); } } @Override public String sign(String signingInput) throws Exception { if (Strings.isNullOrEmpty(signingInput)) { throw new Exception("Invalid signing input"); } try { RSAPrivateKeySpec rsaPrivateKeySpec = new RSAPrivateKeySpec( rsaPrivateKey.getModulus(), rsaPrivateKey.getPrivateExponent()); KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC"); PrivateKey privateKey = keyFactory.generatePrivate(rsaPrivateKeySpec); Signature signature = Signature.getInstance(getSignatureAlgorithm().getAlgorithm(), "BC"); signature.initSign(privateKey); signature.update(signingInput.getBytes(Util.UTF8_STRING_ENCODING)); return Base64Util.base64urlencode(signature.sign()); } catch (NoSuchAlgorithmException e) { throw new Exception("There was a problem in RSA signing", e); } catch (UnsupportedEncodingException e) { throw new Exception("There was a problem in RSA signing", e); } catch (SignatureException e) { throw new Exception("There was a problem in RSA signing", e); } catch (NoSuchProviderException e) { throw new Exception("There was a problem in RSA signing", e); } catch (InvalidKeyException e) { throw new Exception("There was a problem in RSA signing", e); } catch (InvalidKeySpecException e) { throw new Exception("There was a problem in RSA signing", e); } } @Override public boolean verifySignature(String signingInput, String signature) throws Exception { if (Strings.isNullOrEmpty(signingInput)) { return false; } if (Strings.isNullOrEmpty(signature)) { return false; } try { byte[] signatureBytes = Base64Util.base64urldecode(signature); RSAPublicKeySpec rsaPublicKeySpec = new RSAPublicKeySpec( rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent()); KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC"); PublicKey publicKey = keyFactory.generatePublic(rsaPublicKeySpec); Signature verifier = Signature.getInstance(getSignatureAlgorithm().getAlgorithm(), "BC"); verifier.initVerify(publicKey); verifier.update(signingInput.getBytes()); return verifier.verify(signatureBytes); } catch (NoSuchAlgorithmException e) { throw new Exception("There was a problem in RSA verifier", e); } catch (SignatureException e) { throw new Exception("There was a problem in RSA verifier", e); } catch (NoSuchProviderException e) { throw new Exception("There was a problem in RSA verifier", e); } catch (InvalidKeyException e) { throw new Exception("There was a problem in RSA verifier", e); } catch (InvalidKeySpecException e) { throw new Exception("There was a problem in RSA verifier", e); } } }