diff --git a/conf/config.neon b/conf/config.neon
index 099a7e214b..1455cbd909 100644
--- a/conf/config.neon
+++ b/conf/config.neon
@@ -1580,6 +1580,11 @@ services:
 		tags:
 			- phpstan.dynamicFunctionThrowTypeExtension
 
+	-
+		class: PHPStan\Type\Php\OpensslCipherFunctionsReturnTypeExtension
+		tags:
+			- phpstan.broker.dynamicFunctionReturnTypeExtension
+
 	-
 		class: PHPStan\Type\Php\OpenSslEncryptParameterOutTypeExtension
 		tags:
diff --git a/src/Type/Php/OpensslCipherFunctionsReturnTypeExtension.php b/src/Type/Php/OpensslCipherFunctionsReturnTypeExtension.php
new file mode 100644
index 0000000000..e13c83f481
--- /dev/null
+++ b/src/Type/Php/OpensslCipherFunctionsReturnTypeExtension.php
@@ -0,0 +1,88 @@
+<?php declare(strict_types = 1);
+
+namespace PHPStan\Type\Php;
+
+use PhpParser\Node\Expr\FuncCall;
+use PHPStan\Analyser\Scope;
+use PHPStan\Php\PhpVersion;
+use PHPStan\Reflection\FunctionReflection;
+use PHPStan\Reflection\ParametersAcceptorSelector;
+use PHPStan\Type\Constant\ConstantBooleanType;
+use PHPStan\Type\Constant\ConstantStringType;
+use PHPStan\Type\DynamicFunctionReturnTypeExtension;
+use PHPStan\Type\Type;
+use PHPStan\Type\TypeCombinator;
+use function array_map;
+use function array_unique;
+use function count;
+use function function_exists;
+use function in_array;
+use function is_null;
+use function openssl_get_cipher_methods;
+use function strtoupper;
+
+final class OpensslCipherFunctionsReturnTypeExtension implements DynamicFunctionReturnTypeExtension
+{
+
+	/** @var string[]|null */
+	private ?array $supportedAlgorithms = null;
+
+	public function __construct(private PhpVersion $phpVersion)
+	{
+	}
+
+	public function isFunctionSupported(FunctionReflection $functionReflection): bool
+	{
+		return in_array($functionReflection->getName(), ['openssl_cipher_iv_length', 'openssl_cipher_key_length'], true);
+	}
+
+	public function getTypeFromFunctionCall(FunctionReflection $functionReflection, FuncCall $functionCall, Scope $scope): ?Type
+	{
+		if (!$this->phpVersion->throwsValueErrorForInternalFunctions()) {
+			return null;
+		}
+
+		if (count($functionCall->getArgs()) < 1) {
+			return null;
+		}
+
+		$strings = $scope->getType($functionCall->getArgs()[0]->value)->getConstantStrings();
+		$results = array_unique(array_map(fn (ConstantStringType $algorithm): bool => $this->isSupportedAlgorithm($algorithm->getValue()), $strings));
+
+		if (count($results) !== 1) {
+			return null;
+		}
+
+		$returnType = ParametersAcceptorSelector::selectFromArgs(
+			$scope,
+			$functionCall->getArgs(),
+			$functionReflection->getVariants(),
+		)->getReturnType();
+
+		return $results[0]
+			? TypeCombinator::remove($returnType, new ConstantBooleanType(false))
+			: new ConstantBooleanType(false);
+	}
+
+	private function isSupportedAlgorithm(string $algorithm): bool
+	{
+		return in_array(strtoupper($algorithm), $this->getSupportedAlgorithms(), true);
+	}
+
+	/** @return string[] */
+	private function getSupportedAlgorithms(): array
+	{
+		if (!is_null($this->supportedAlgorithms)) {
+			return $this->supportedAlgorithms;
+		}
+
+		$supportedAlgorithms = [];
+		if (function_exists('openssl_get_cipher_methods')) {
+			$supportedAlgorithms = openssl_get_cipher_methods(true);
+		}
+		$this->supportedAlgorithms = array_map('strtoupper', $supportedAlgorithms);
+
+		return $this->supportedAlgorithms;
+	}
+
+}
diff --git a/tests/PHPStan/Analyser/nsrt/openssl-cipher-iv-length-php7.php b/tests/PHPStan/Analyser/nsrt/openssl-cipher-iv-length-php7.php
new file mode 100644
index 0000000000..72b8c41b87
--- /dev/null
+++ b/tests/PHPStan/Analyser/nsrt/openssl-cipher-iv-length-php7.php
@@ -0,0 +1,24 @@
+<?php // lint < 8.0
+
+namespace OpensslCipherIvLengthPhp7;
+
+use function PHPStan\Testing\assertType;
+
+class OpensslCipher
+{
+
+	/**
+	 * @param 'aes-256-cbc'|'aes128'|'aes-128-cbc' $validAlgorithms
+	 * @param 'aes-256-cbc'|'invalid' $validAndInvalidAlgorithms
+	 */
+	public function doFoo(string $s, $validAlgorithms, $validAndInvalidAlgorithms)
+	{
+		assertType('int|false', openssl_cipher_iv_length('aes-256-cbc'));
+		assertType('int|false', openssl_cipher_iv_length('AES-256-CBC'));
+		assertType('int|false', openssl_cipher_iv_length('unsupported'));
+		assertType('int|false', openssl_cipher_iv_length($s));
+		assertType('int|false', openssl_cipher_iv_length($validAlgorithms));
+		assertType('int|false', openssl_cipher_iv_length($validAndInvalidAlgorithms));
+	}
+
+}
diff --git a/tests/PHPStan/Analyser/nsrt/openssl-cipher-iv-length-php8.php b/tests/PHPStan/Analyser/nsrt/openssl-cipher-iv-length-php8.php
new file mode 100644
index 0000000000..108e1bf119
--- /dev/null
+++ b/tests/PHPStan/Analyser/nsrt/openssl-cipher-iv-length-php8.php
@@ -0,0 +1,24 @@
+<?php // lint >= 8.0
+
+namespace OpensslCipherIvLengthPhp8;
+
+use function PHPStan\Testing\assertType;
+
+class OpensslCipher
+{
+
+	/**
+	 * @param 'aes-256-cbc'|'aes128'|'aes-128-cbc' $validAlgorithms
+	 * @param 'aes-256-cbc'|'invalid' $validAndInvalidAlgorithms
+	 */
+	public function doFoo(string $s, $validAlgorithms, $validAndInvalidAlgorithms)
+	{
+		assertType('int', openssl_cipher_iv_length('aes-256-cbc'));
+		assertType('int', openssl_cipher_iv_length('AES-256-CBC'));
+		assertType('false', openssl_cipher_iv_length('unsupported'));
+		assertType('int|false', openssl_cipher_iv_length($s));
+		assertType('int', openssl_cipher_iv_length($validAlgorithms));
+		assertType('int|false', openssl_cipher_iv_length($validAndInvalidAlgorithms));
+	}
+
+}
diff --git a/tests/PHPStan/Analyser/nsrt/openssl-cipher-key-length.php b/tests/PHPStan/Analyser/nsrt/openssl-cipher-key-length.php
new file mode 100644
index 0000000000..c9081ae67c
--- /dev/null
+++ b/tests/PHPStan/Analyser/nsrt/openssl-cipher-key-length.php
@@ -0,0 +1,24 @@
+<?php // lint >= 8.2
+
+namespace OpensslCipherKeyLength;
+
+use function PHPStan\Testing\assertType;
+
+class OpensslCipher
+{
+
+	/**
+	 * @param 'aes-256-cbc'|'aes128'|'aes-128-cbc' $validAlgorithms
+	 * @param 'aes-256-cbc'|'invalid' $validAndInvalidAlgorithms
+	 */
+	public function doFoo(string $s, $validAlgorithms, $validAndInvalidAlgorithms)
+	{
+		assertType('int', openssl_cipher_key_length('aes-256-cbc'));
+		assertType('int', openssl_cipher_key_length('AES-256-CBC'));
+		assertType('false', openssl_cipher_key_length('unsupported'));
+		assertType('int|false', openssl_cipher_key_length($s));
+		assertType('int', openssl_cipher_key_length($validAlgorithms));
+		assertType('int|false', openssl_cipher_key_length($validAndInvalidAlgorithms));
+	}
+
+}