我有一个外部服务,在定义的事件发生后会给我回电,并用其私钥签署他的请求。
我已经存储了如下公钥:
-----BEGIN PUBLIC KEY-----
........................................
-----END PUBLIC KEY-----
因此,我的工作是通过验证签名来检查请求的内容是否未更改。
这是我的算法:
// 1 - reading public key :
Scanner scanner = new Scanner( new File( keyPath ) );
// encodedPublicKey.toString( );
StringBuilder sb = new StringBuilder( );
while ( scanner.hasNextLine( ) )
{
sb.append( scanner.nextLine( ) );
sb.append( '\n' );
}
byte[] encodedPublicKey = sb.toString( ).getBytes( "utf-8" );
// 2 - loading public key in a relevant object :
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec( publicKeyBytes );
KeyFactory keyFactory = KeyFactory.getInstance( "DSA" );
PublicKey publicKey = keyFactory.generatePublic( publicKeySpec );
// 3 - verifying content with signature and content :
Signature sig = Signature.getInstance( "SHA1withDSA" );
sig.initVerify( publicKey );
sig.update( message.getBytes( ) );
ret = sig.verify( sign.getBytes( ) );
但是目前,我的算法已停止在此消息的“ PublicKey publicKey =
keyFactory.generatePublic(publicKeySpec)”步骤处:
java.security.spec.InvalidKeySpecException: Inappropriate key specification: invalid key format
那么,如何以java api接受的方式加载密钥?
其实我已经找到了解决方案。
问题在于以正确的方式加载公钥文件。
我将bouncycastle库添加到我的依赖项中:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.47</version>
</dependency>
它提供了PemReader,它允许读取和加载未认证的公共密钥。
这是我的实用程序类:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import org.bouncycastle.util.io.pem.PemReader;
import org.castor.util.Base64Decoder;
import fr.paris.lutece.portal.service.util.AppLogService;
/**
* Classe d'aide à l'interfacage avec le service paybox.
*
* Toutes les informations parameterables sont sous la forme paybox.*
*/
public final class PayboxUtil
{
/** The Constant CHARSET. */
private static final String CHARSET = "utf-8";
/** The Constant ENCRYPTION_ALGORITHM. */
private static final String ENCRYPTION_ALGORITHM = "RSA";
/** The Constant HASH_ENCRIPTION_ALGORITHM. */
private static final String HASH_ENCRYPTION_ALGORITHM = "SHA1withRSA";
/**
* constructeur privé pour classe statique.
*/
private PayboxUtil( )
{
}
/**
* Controle si une signature est bien celle du message à l'aide de la clé
* publique de l'emmeteur?.
*
* @param message le message
* @param sign la signature
* @param keyPath le chemin vers la clé publique.
* @return true si la signature est bien celle du message avec la clé privé
* attendue.
*/
public static boolean checkSign( String message, String sign, String keyPath )
{
boolean ret = false;
try
{
ret = PayboxUtil.verify( message, sign, PayboxUtil.getKey( keyPath ) );
}
catch ( final FileNotFoundException e )
{
AppLogService.error( e );
}
catch ( final IOException e )
{
AppLogService.error( e );
}
catch ( final NoSuchAlgorithmException e )
{
AppLogService.error( e );
}
catch ( final InvalidKeySpecException e )
{
AppLogService.error( e );
}
catch ( final InvalidKeyException e )
{
AppLogService.error( e );
}
catch ( final SignatureException e )
{
AppLogService.error( e );
}
return ret;
}
/**
* Récupère la clé publique à partir du chemin passé en paramètre.
*
* @param keyPath le chemin vers la clé.
* @return la clé publique
* @throws NoSuchAlgorithmException the no such algorithm exception
* @throws IOException Signals that an I/O exception has occurred.
* @throws InvalidKeySpecException the invalid key spec exception
*/
private static PublicKey getKey( String keyPath )
throws NoSuchAlgorithmException, IOException, InvalidKeySpecException
{
final KeyFactory keyFactory = KeyFactory.getInstance( PayboxUtil.ENCRYPTION_ALGORITHM );
final PemReader reader = new PemReader( new FileReader( keyPath ) );
final byte[] pubKey = reader.readPemObject( ).getContent( );
final X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec( pubKey );
return keyFactory.generatePublic( publicKeySpec );
}
/**
* effectue la vérification du message en fonction de la signature et de la
* clé.
*
* @param message le message
* @param sign la signature
* @param publicKey la clé publique.
* @return true, if successful
* @throws NoSuchAlgorithmException the no such algorithm exception
* @throws InvalidKeyException the invalid key exception
* @throws SignatureException the signature exception
* @throws UnsupportedEncodingException the unsupported encoding exception
*/
private static boolean verify( String message, String sign, PublicKey publicKey )
throws NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException
{
final Signature sig = Signature.getInstance( PayboxUtil.HASH_ENCRYPTION_ALGORITHM );
sig.initVerify( publicKey );
sig.update( message.getBytes( PayboxUtil.CHARSET ) );
final byte[] bytes = Base64Decoder.decode( URLDecoder.decode( sign, PayboxUtil.CHARSET ) );
return sig.verify( bytes );
}
}
您只需要将签名内容,签名和密钥路径传递给checkSign方法即可完成所有工作。
验证应用程序: 据我所知.pfx文件包含公钥和私钥信息,因此我不应该让任何人都可以使用它。据我所知,验证步骤只需要公钥。我如何使用rsa.verifydata或其他函数来验证签名而不暴露我的pfx文件?
我需要用DSA公钥验证X509证书签名。我的证书文件x509.crt,我的DSA公钥在一个名为dsa_pub.key的文件中 我正试图为此使用openssl。我已经阅读了openssl验证文档,但在其中找不到任何有关DSA的参考。 当我运行以下命令时,我可以在证书中看到我的DSA公钥: 但是,在使用文件DSA_pub.key中的DSA公钥验证cert.crt时,我遇到了麻烦 如果您有任何建议,我将
我的理解是公钥加密,私钥解密...有谁能帮我弄明白吗?
我需要验证来自Microsoft图形API的令牌签名。我知道所使用的签名键的指纹在JWT的标题中: 它对应于您可以从已知endpoint获得的密钥: https://login.microsoftonline.com/[TENANT-ID]/发现/v2.0/key 我的计划是将密钥列表存储在缓存中,以便在需要进行验证时可以查找令牌的正确签名密钥。然而,我明白有时键可能会旋转。 由于没有太多关于这方
我想验证一些来自Microsoft的JWT的签名。我正在使用Spring-Boot、JJWT库和以下endpoint:https://login.microsoftonline.com/common/discovery/v2.0/keys endpoint返回JSON公钥数组。下面是数组中的一个示例。
通常情况下,访问远程服务器上的 Git 仓库要受到限制。你可能不希望任何人都能读取文件,或者至少不能改动文件吧。在这种情况下,进行有效的认证就是非常必要地。 你可能已经通过你所使用的浏览器了解了 “HTTPS” 协议,尽管它使用起来很简单,但是很多系统管理员还是会出于各种原因去选择使用更为普遍的 “SSH” 协议。在这种协议之下,当涉及到身份验证时,你就很可能需要 “SSH公钥”。 对于这种类型的