jwt使用rsa加密时报错(main方法测试始终正确,一使用web运行就报错)

错误信息

java.security.InvalidKeyException: IOException: DerInputStream.getLength(): lengthTag=13, too big.

原因:多线程引起的并发问题(更具体的原因不清楚)。

解决:使用synchronized (或者Lock,我懒得用Lock了)

	/**
	 * 从文件中获取公钥
	 * 
	 * @param publicKeyFilePath
	 *            文件路径
	 * @return
	 */
	public synchronized static PublicKey getPublicKey(String publicKeyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
		return getPublicKey(new FileInputStream(publicKeyFilePath));
	}

	/**
	 * 从文件中获取公钥
	 * 
	 * @param publicKeyFilePath
	 *            classpath中的文件相对路径(只有文件名都行,ClassLoader.getResourceAsStream会自行搜索)
	 * @return
	 */
	public synchronized static PublicKey getPublicKeyClasspath(String publicKeyFilePath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
		return getPublicKey(RsaKeyUtil.class.getClassLoader().getResourceAsStream(publicKeyFilePath));
	}

	/**
	 * 从字节输入流中获取公钥
	 * 
	 * @param publicKeyInput
	 * @return
	 * @throws IOException
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 */
	public synchronized static PublicKey getPublicKey(InputStream publicKeyInput) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
		try (InputStream input = publicKeyInput; DataInputStream dis = new DataInputStream(input)) {
			byte[] keyBytes = new byte[input.available()];
			dis.readFully(keyBytes);
			X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
			KeyFactory kf = KeyFactory.getInstance("RSA");
			return kf.generatePublic(spec);
		}
	}

	public synchronized static PublicKey getPublicKey64(String publicKeyFilePath) throws Exception {
		return getPublicKey64(new FileInputStream(publicKeyFilePath));
	}

	public synchronized static PublicKey getPublicKey64Classpath(String publicKeyFilePath) throws Exception {
		return getPublicKey64(RsaKeyUtil.class.getClassLoader().getResourceAsStream(publicKeyFilePath));
	}

	public synchronized static PublicKey getPublicKey64(InputStream publicKeyInput) throws Exception {
		try (InputStream input = publicKeyInput) {
			String key64 = FileUtil.readAllString(input);
			byte[] keyByte = Base64Util.decodeBase64(key64);
			X509EncodedKeySpec spec = new X509EncodedKeySpec(keyByte);
			KeyFactory kf = KeyFactory.getInstance("RSA");
			return kf.generatePublic(spec);
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
flask_jwt_extended是一个用于Flask应用程序的JSON Web Token (JWT)扩展,它可以帮助你轻松地保护你的API。下面是一个使用RSA非对称加密的示例: 1. 安装所需的依赖 ``` pip install flask flask_jwt_extended cryptography ``` 2. 生成RSA密钥对 ``` from cryptography.hazmat.primitives.asymmetric import rsa, padding from cryptography.hazmat.primitives import serialization private_key = rsa.generate_private_key( public_exponent=65537, key_size=2048, ) public_key = private_key.public_key() # 保存私钥 with open('private_key.pem', 'wb') as f: f.write(private_key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=serialization.NoEncryption() )) # 保存公钥 with open('public_key.pem', 'wb') as f: f.write(public_key.public_bytes( encoding=serialization.Encoding.PEM, format=serialization.PublicFormat.SubjectPublicKeyInfo )) ``` 3. 使用RSA密钥对进行JWT签名和验证 ``` from flask import Flask, jsonify from flask_jwt_extended import JWTManager, create_access_token, jwt_required from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend app = Flask(__name__) app.config['JWT_SECRET_KEY'] = 'super-secret' # 这个密钥不用于签名,只用于加密 app.config['JWT_ALGORITHM'] = 'RS256' jwt = JWTManager(app) # 加载RSA密钥 with open('private_key.pem', 'rb') as f: private_key = serialization.load_pem_private_key( f.read(), password=None, backend=default_backend() ) with open('public_key.pem', 'rb') as f: public_key = serialization.load_pem_public_key( f.read(), backend=default_backend() ) @app.route('/login') def login(): access_token = create_access_token( identity='user_id', algorithm='RS256', private_key=private_key ) return jsonify(access_token=access_token) @app.route('/protected') @jwt_required(algorithms=['RS256'], public_key=public_key) def protected(): return jsonify({'message': 'protected'}) if __name__ == '__main__': app.run() ``` 在这个示例中,我们使用RSA非对称加密算法来对JWT进行签名和验证。在生成JWT时,我们使用私钥来签名,而在验证JWT时,我们使用公钥来验证签名。使用RSA非对称加密算法可以更安全地保护JWT

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值