public static java.security.Signature sigMeth2SigSignatureInstance(Signature sig, Key key) throws DigiDocException { java.security.Signature instance = null; String sigMeth = null, sigType = null; try { if (sig != null && sig.getSignedInfo() != null && sig.getSignedInfo().getSignatureMethod() != null) sigMeth = sig.getSignedInfo().getSignatureMethod(); sigType = ConfigManager.instance().sigMeth2SigType(sigMeth, true); // allways use cvc ciphers if (m_logger.isDebugEnabled()) m_logger.debug( "Key: " + ((key != null) ? "OK, algorithm: " + key.getAlgorithm() : "NULL") + " method: " + sigMeth + " type: " + sigType); if (sigType == null) throw new DigiDocException( DigiDocException.ERR_SIGNATURE_METHOD, "SignatureMethod not specified!", null); instance = java.security.Signature.getInstance(sigType, ConfigManager.addProvider()); } catch (Exception ex) { m_logger.error("Error constructing signature instance: " + ex); } return instance; }
/** * Method returns a digital signature. It finds the RSA private key object from the active token * and then signs the given data with this key and RSA mechanism. * * @param digest digest of the data to be signed. * @param token token index * @param passwd users pin code or in case of pkcs12 file password * @param sig Signature object to provide info about desired signature method * @return an array of bytes containing digital signature. * @throws DigiDocException if signing the data fails. */ public byte[] sign(byte[] xml, int token, String passwd, Signature sig) throws DigiDocException { try { if (m_keyStore == null) throw new DigiDocException( DigiDocException.ERR_NOT_INITED, "Keystore not initialized", null); String alias = getTokenName(token); if (alias == null) throw new DigiDocException( DigiDocException.ERR_TOKEN_LOGIN, "Invalid token nr: " + token, null); // get key if (m_logger.isDebugEnabled()) m_logger.debug( "loading key: " + alias + " passwd-len: " + ((passwd != null) ? passwd.length() : 0)); Key key = m_keyStore.getKey(alias, passwd.toCharArray()); if (m_logger.isDebugEnabled()) m_logger.debug("Key: " + ((key != null) ? "OK, algorithm: " + key.getAlgorithm() : "NULL")); if (key == null) throw new DigiDocException( DigiDocException.ERR_TOKEN_LOGIN, "Invalid password for token nr: " + token, null); String sigMeth = null; if (sig != null && sig.getSignedInfo() != null && sig.getSignedInfo().getSignatureMethod() != null) sigMeth = sig.getSignedInfo().getSignatureMethod(); if (m_logger.isDebugEnabled()) m_logger.debug("Signing\n---\n" + new String(xml) + "\n---\n method: " + sigMeth); java.security.Signature instance = sigMeth2SigSignatureInstance(sig, key); if (m_logger.isDebugEnabled()) m_logger.debug("Signature instance: " + ((instance != null) ? "OK" : "NULL")); instance.initSign((PrivateKey) key); instance.update(xml); byte[] signature = instance.sign(); boolean bEcCvcKey = isCvcEcKey(sig); if (m_logger.isDebugEnabled()) m_logger.debug( "Signature algorithm: " + key.getAlgorithm() + " siglen: " + signature.length + " ec-key: " + bEcCvcKey); if (bEcCvcKey) { int nKeyLen = ((ECPrivateKey) key).getParams().getCurve().getField().getFieldSize(); int nReqLen = ((int) Math.ceil((double) nKeyLen / 8)) * 2; int nSigLen = signature.length; if (m_logger.isDebugEnabled()) m_logger.debug("EC Signature length: " + nSigLen + " required: " + nReqLen); if (nSigLen < nReqLen) { if (m_logger.isDebugEnabled()) m_logger.debug("Padding EC signature length: " + nSigLen + " to required: " + nReqLen); byte[] padsig = new byte[nReqLen]; System.arraycopy(signature, 0, padsig, (nReqLen - nSigLen) / 2, nSigLen / 2); System.arraycopy( signature, nSigLen / 2, padsig, (nReqLen / 2) + (nReqLen - nSigLen) / 2, nSigLen / 2); signature = padsig; } } if (m_logger.isDebugEnabled() && signature != null) m_logger.debug( "Signature len: " + signature.length + "\n---\n sig: " + ConvertUtils.bin2hex(signature)); return signature; } catch (DigiDocException ex) { m_logger.error("DigiDoc Error signing: " + ex); throw ex; } catch (Exception ex) { m_logger.error("Error signing: " + ex); } return null; }
private boolean isCvcEcKey(Signature sig) { String sigMeth = sig.getSignedInfo().getSignatureMethod(); String sSigType = ConfigManager.instance().sigMeth2SigType(sigMeth, true); return ConfigManager.isEcdsaCvcAlgorithm(sSigType); }